Могу ли я обезглавить NilClass, чтобы вернуть нуль за отсутствующие методы?

В других языках, например (objective-c например) вызов метода на объекте nil терпит неудачу и возвращает nil, но в ruby ​​вы получаете такие ошибки...

undefined method `some_method' for nil:NilClass

который (для меня) приводит к следующему коду:

if some_object && some_object.cool? # instead of if some_object.cool?
 # do some cool stuff
end

или

some_object.do_awsome_thing if some_object

Что все кажется обратным и странным.

Два вопроса

  • Что я делаю неправильно, что правильный способ справиться с возможностью объекта nil

  • Какие ужасные ужасные вещи произойдут, если я просто обезьяна заплачу за объект nil, чтобы вернуть nil для missing_methods?

IE:

class NilClass
 def missing_method
 nil
 end
end
2 ответа

Это выбор дизайна, и я полагаю, что было бы возможно nil ответить nil на методы, которые он не знает.

Чтобы быть последовательным, вы должны определить respond_to_missing?:

class NilObj
 def method_missing(*_)
 nil
 end
 def respond_to_missing?(*_)
 true
 end
end

Если вы сделали патч обезьяны method_missing, как вы предлагаете, особенно если вы также переопределите respond_to_missing? соответственно, вы можете получить некоторые странные побочные эффекты, так как утиная печать требует некоторой интроспекции, и это обычно делается путем проверки того, реагирует ли объект к чему-то, чем к определенному классу.

Например, тот факт, что nil будет отвечать на to_ary, как представляется, предполагает, что он "подобен массиву", когда это не так.

Некоторые встроенные методы вызовут respond_to?, а некоторые просто вызовут и заберут NoMethodError, поэтому даже без respond_to_missing? вы можете получить некоторые странные побочные эффекты.


Для гораздо более тщательного ответа, чем я мог бы написать, пожалуйста, прочитайте Reg Braithwaite Беспощадная эгоцентрическая статья в блоге

Короткий ответ: некоторые люди думают, что поведение трюка method_missing желательно, но есть подводные камни. Дизайнеры Ruby считают, что поведение по умолчанию не подходит. Другие разработчики языка выбирают иначе (например: Objective-C)

licensed under cc by-sa 3.0 with attribution.