Кристалл: хороший способ выбора методов

Мне нужно передать некоторые опции в метод, некоторые из этих опций являются необязательными (что-то вроде деструктурирования объекта в JS).

Мой текущий код:

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

И я называю это: MyClass.new "Arg", { opt2: "True", opt4: "123" }

Это работает, но я ищу лучший путь. Было бы полезно установить тип каждой опции и иметь значения по умолчанию непосредственно в сигнатуре функции.

Использование NamedTuple кажется хорошим способом, но у меня были проблемы с дополнительными значениями - options : NamedTuple( opt1: String, opt2: Bool, opt3: String, opt4: Int ) | Nil = nil

Другой способ, который я попробовал, - это структура, но она, похоже, усложняет ситуацию.

1 ответ

Решение

Crystal имеет необязательные и именованные аргументы метода в качестве основных функций языка и не требует написания специального кода для обработки аргументов. Смотрите официальную документацию об аргументах метода. В частности, вот пример:

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

Звездочка не всегда нужна, она только гарантирует, что следующие необязательные аргументы могут быть переданы только по имени:

method("test", opt1: "other value", opt2: false)
Другие вопросы по тегам