Как вам такое проявление «полиморфизма» в rails?
Такой феномен возникает во многих ситуациях и связан он с использованием паттерна проектирования Proxy Class. Конкретно в случае ActionView он возникает при использовании deprecated методов. Подробнее в activesupport/lib/active_support/deprecation.rb (Реализация proxy классов DeprecationProxy и наследников) и в actionpack/lib/action_view/renderable_partial.rb (Их использование).
Смоделировал такую ситуацию для наглядности:
Как видно, поскольку для ^__ undef не делали (в DeprecationProxy тоже не делают), то вычислить таких самозванцев можно по __id__
contact.class
=> NilClass
puts "OK" if contact
OK
=> nil
puts "OK" unless contact
=> nil
contact == nil
=> true
puts "OK" if contact
OK
=> nil
puts "OK" if nil
=> nil
Такой феномен возникает во многих ситуациях и связан он с использованием паттерна проектирования Proxy Class. Конкретно в случае ActionView он возникает при использовании deprecated методов. Подробнее в activesupport/lib/active_support/deprecation.rb (Реализация proxy классов DeprecationProxy и наследников) и в actionpack/lib/action_view/renderable_partial.rb (Их использование).
Смоделировал такую ситуацию для наглядности:
class ProxyClass
silence_warnings { instance_methods.each { |m| undef_method m unless m =~ /^__/ } }
def initialize(target)
@target = target
end
private
def method_missing(called, *args, &block)
@target.__send__(called, *args, &block)
end
end
Смотрим:
>> @nil_object1 = nil
=> nil
>> @nil_object2 = ProxyClass.new(@nil_object1)
=> nil
>> @nil_object1.object_id
=> 4
>> @nil_object2.object_id
=> 4
>> @nil_object2.__id__
=> 2198992980
>> @nil_object1.__id__
=> 4
Как видно, поскольку для ^__ undef не делали (в DeprecationProxy тоже не делают), то вычислить таких самозванцев можно по __id__