Как создать объект в ruby, который будет вычисляться как false в логических выражениях, подобных nil?
Мое намерение состоит в том, чтобы разрешить вложенные вызовы для других объектов, где где-то на половину пути вниз по цепочке значение обычно будет nil
, но разрешить все вызовы продолжить - возврат моего нулевого объекта вместо nil
. Объект вернется в ответ на любые принятые сообщения, которые он не знает, как обращаться, и я ожидаю, что мне нужно будет реализовать некоторые методы переопределения, такие как nil?
.
Например:
fizz.buzz.foo.bar
Если свойство buzz
для fizz
недоступно, я бы вернул свой нулевой объект, который будет принимать вызовы вплоть до bar
, возвращаясь. В конечном итоге приведенное выше утверждение должно оцениваться как false.
Edit:
Основываясь на всех замечательных ответах ниже, я придумал следующее:
class NilClass
attr_accessor :forgiving
def method_missing(name, *args, &block)
return self if @forgiving
super
end
def forgive
@forgiving = true
yield if block_given?
@forgiving = false
end
end
Это позволяет использовать некоторые подлые трюки:
nil.forgiving {
hash = {}
value = hash[:key].i.dont.care.that.you.dont.exist
if value.nil?
# great, we found out without checking all its parents too
else
# got the value without checking its parents, yaldi
end
}
Очевидно, что вы можете обернуть этот блок прозрачно внутри некоторого функции call/class/module/wherever.