Если obj не является экземпляром String, а отвечает на to_str, то две строки сравниваются с использованием равенства case Object # ===.
В вашем случае foo
отвечает #to_str
, но не экземпляр String
. Так в 'some_txt' === foo
на самом деле использует Object#===
Случай равенства - Для класса Object
, фактически то же самое, как вызов #==
, но, как правило, переопределяется потомков, чтобы обеспечить осмысленные семантику в случае заявления.
Foo
является потомком класса из Object
. Любой класс в Ruby по умолчанию наследует от Object
. Теперь Foo
не переопределил метод #===
, поэтому в соответствии с документацией он будет использовать метод Object#==
. Документация Object#==
говорит:
Равенство - На Object
уровне ==
возвращает истинный только если obj
и other
являются же объект. Как правило, этот метод переопределяется в классах потомков, чтобы обеспечить значение, специфичное для класса.
В соответствии с вышеуказанным принципа - в качестве 'some_txt'
экземпляра String
и foo
является экземпляром Foo
, 'some_txt' === foo
(который на самом деле foo == 'some_txt'
, поскольку Object#===
делегирует вызов в Object#==
) дает false
.
Документация Object#==
и Object#===
как говорит -
Как правило, этот метод переопределяется в классах-потомках, чтобы обеспечить значение класса специфические.
Это означает, что вы можете переопределить либо Object#===
или Object#==
реализовать логику сравнений. Просто, чтобы имитировать то, что я только что сказал, я ставлю один фиктивный пример кода: -
class Foo
def to_str
'some_txt'
end
def ==(other)
true
end
end
foo = Foo.new
'some_txt' === foo # => true
foo.class.superclass # => Object
Вы могли бы реализовать 'Foo # ==' 'переопределить Object # ==' – Stefan
@Stefan Именно это точка. –
Вероятно, у вас есть правильные рассуждения, но ваш заказ на презентацию не работает логически. Вы хотите показать, что в этом случае '' some_txt '=== foo' использует 'Object # ===' (не 'Object # =='), а затем вы хотите показать, что 'Object # === 'использует' Object # == ', если он не переопределен. – sawa