Ruby nil-like object

Как я могу создать объект в ruby, который будет оцениваться как false в логических выражениях, подобных nil?

Моя цель - включить вложенные вызовы других объектов, где где-то на полпути вниз по цепочке значение обычно будет nil, но позволить всем вызовам продолжаться, возвращая мой nil-подобный объект вместо nil самого объекта. Объект будет возвращать себя в ответ на любые полученные сообщения, которые он не знает, как обработать, и я предполагаю, что мне понадобится реализовать некоторые переопределенные методы, такие как nil?.

Например:

fizz.buzz.foo.bar

Если бы свойство buzz свойства fizz не было доступно, я бы вернул свой nil-подобный объект, который будет принимать вызовы вплоть до 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
}

Очевидно, что вы можете обернуть этот блок прозрачно внутри какого-нибудь вызова функции/класса/модуля/где угодно.

12
задан Dave Schweisguth 18 February 2016 в 13:39
поделиться