Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Input subclass constructors force use of positional arguments #14

Open
DanRathbun opened this issue Sep 29, 2021 · 3 comments
Open

Input subclass constructors force use of positional arguments #14

DanRathbun opened this issue Sep 29, 2021 · 3 comments

Comments

@DanRathbun
Copy link
Contributor

HtmlUI::Input subclass constructors force use of positional arguments.

This is becoming a problem in adding more features.

One is adding a key: "keyname" argument for hash output.

@DanRathbun
Copy link
Contributor Author

DanRathbun commented Sep 30, 2021

My goal is to be able to use a pattern like this:

  def get_profile

    name = HtmlUI::Textbox.new(
      key: :name,
      label: "Name"
    )

    age = HtmlUI::Textbox.new(
      key: :age,
      label: "Age (to the nearest year)",
      default: Integer,
      width: 4
    )

    height = HtmlUI::Textbox.new(
      key: :height,
      label: "Height",
      default: Length,
      width: 10
    )

    drink = HtmlUI::Dropdown.new(
      key: :poison,
      label: "Choose your poison:",
      default: "Brandy",
      options: ["Bourbon","Brandy","Whiskey","Wine"]
    )

    hobby = HtmlUI::Listbox.new(
      key: :hobby,
      label: "Choose your favorite pasttime:",
      default: "Golf",
      options: ["Golf","Tennis","Squash","Fishing"],
      rows: 4
    )

    window = HtmlUI::InputBox.new(
      title: "Personality Profile",
      inputs: [ name, age, height, drink, hobby ]
    )

    data = window.prompt(Hash)

    # data validation ...

  end

One advantage is that any mistakes in calling input control constructors will raise exceptions that are not nested within the HtmlUI::InputBox constructor. So better code debugging. When all the input control constructors "pass muster" then the :inputs array for the HtmlUI::InputBox constructor should be fine and dandy.

@thomthom
Copy link
Member

Yes, when looking at the examples as I was replying to one of the other threads I was bothered how unclear it was to read which argument was the default one. Named arguments is preferable, particularly when you have more than a couple of arguments like in these cases.

@DanRathbun
Copy link
Contributor Author

DanRathbun commented Sep 30, 2021

You're right. For instance, I'm not happy about the constructor signatures for the various controls. I'm thinking default value should be a named argument and not positional.

I have no problem with allowing a small set of positional args to default to their matching named args.

Need to rethink the interface as a whole I think.

You already correctly have the 3 "base" arguments (:label, :default, :options) as positional arguments.
Just need to rewrite the initialize methods so that they also accept named arguments, along with new named arguments that we may not yet have thought of. (In addition to a :key argument, I'm thinking sizing [width and rows], position, and perhaps styling properties here. Oh! yes, and also validation properties, like :range, required, :min, :max, etc. )

Do not think myself that we need a total overhaul.

Might have to play around with some mock-code to explore alternatives.

To make things easier at the console I do this:

UX = Example::HtmlInputBox::HtmlUI

... then I can enter tests like so:

dlg = UX::InputBox.new(
  title: "Enter Data...",
  inputs: [ UX::Textbox.new("Name"), UX::Textbox.new("Age",Integer), UX::Textbox.new("Height",Length) ]
)

And adding manually passed in IDs will then quickly make the interface cumbersome.

I think as said in the other thread, it's no problem adding a input[:key] argument.

The only other alternative is a loose coupling by having the :inputs argument for InputBox::new be a hash of input objects rather than an array of input objects.

I am not really keen on this as many places in the code the inputs are iterated by index and switching to a hash would greatly complicates dual use. The compatibility shim uses ordered arguments, but you cannot know what order the keys of a hash will be returned in.

I also like the idea that an input object "knows" what it's :key is. (I see it as a property of the input object.)

I like the way I am now leaning to let the developer decide on a input by input basis what the key will be ... either the default to the :label or an explicit :key.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants