Я надеюсь, вы, ребята, поможете мне решить, какое поведение будет более «стандартным» или «ожидаемым».Значение аргумента аргумента метода Ruby, неявное vs literal nil, ответственность библиотеки или вызывающие?
фона:
В Ruby вы можете предоставить аргументы по умолчанию для метода, например.
def tester(input={})
input
end
Если вы звоните tester
вы получаете {}
. Однако если вы звоните tester(nil)
, вы получаете nil
.
Честно говоря, что меня удивило, я полагал, что вы получите {}
, если вы прошли nil
методу, потому что я всегда представлял заявление input={}
в определении метода быть сродни input ||= {}
, но очевидно, что это больше похоже defined?(input) ? input : {}
.
Вопрос:
В библиотеке я утверждаю, у меня есть класс, который принимает необязательный хэш инициализации. Инициализатором выглядит точно так же, как тестер выше:
def initialize(input={})
Таким образом, вы можете позвонить MyClass.new
или MyClass.new foo:1
, но вы не можете назвать MyClass.new nil
Это кажется очевидным, за исключением случаев использования переменных инициализации, например. MyClass.new(opts)
, где opts может быть хэш или ноль.
Я мог бы изменить способ это работает, изменяя реализацию, как так:
def initialize(input=nil)
input ||= {}
...
end
Но я оставил интересно, это правильный дизайн для интерфейса Ruby?
Должен ли я ожидать, что вызывающий абонент будет использовать MyClass.new(opts || {})
?
Если вы используете библиотеку, и есть класс в этой библиотеке, который принимает необязательный хеш, вы ожидаете, что будет безопасно передать nil
инициализатору и для этого следует рассматривать как эквивалент пропуска без аргумента ? Или вы ожидаете, что это сломается, потому что в Ruby, проходящий буквальный ноль, это не то же самое, что передать аргумент?
Какой дизайн выглядит более «правильным» для вас?
Либо. Это зависит от ожидаемых шаблонов использования. – jrochkind