Mat
Mat

Reputation: 2184

Crystal: a good way for method options

I need to pass some options to a method, some of these options are optional (something like Object destructuring in JS).

My current code:

def initialize( arg1 : String, options = {} of Symbol => String )
  opt = MyClass.get_option options, :opt1
  @opt1 = !opt.empty? ? opt : "Def value"
  opt = MyClass.get_option options, :opt2
  @opt2 = !opt.empty? ? opt : "False"
  # ...
end
def self.get_option( options, key : Symbol )
  ( options && options[key]? ) ? options[key].strip : ""
end

And I call it: MyClass.new "Arg", { opt2: "True", opt4: "123" }

It works but I'm looking for a better way. It would be useful to set the type of each option and to have default values directly in the function signature.

Using a NamedTuple seems a good way but I had problems with optional values - options : NamedTuple( opt1: String, opt2: Bool, opt3: String, opt4: Int ) | Nil = nil

Another way that I tried is with a struct but it seems to complicate the situation.

Upvotes: 3

Views: 586

Answers (1)

Oleh Prypin
Oleh Prypin

Reputation: 34116

Crystal has optional and named method arguments as core language features, and does not require writing special code for handling the arguments. See the official documentation about Method arguments. In particular, here is an example:

def method(arg1 : String, *, opt1 = "Def value", opt2 = false)

The asterisk is not always needed, it only ensures that the following optional arguments can only be passed by name:

method("test", opt1: "other value", opt2: false)

Upvotes: 3

Related Questions