Ответ 1
как получается > рассматривается как метод, но он является логическим оператором?
Нет проблем с этим. В Ruby, когда вы пишете выражение типа 1 + 2
, внутри него понимается 1.+( 2 )
: метод вызова #+
на приемнике 1
с 2
как один аргумент. Другой способ понять то же самое, что вы отправляете сообщение [ :+, 2 ]
объекту 1
.
в чем причина ошибки?
Теперь в вашем случае @state_turns[ state.id ]
по какой-то причине возвращает nil
. Таким образом, выражение @state_turns[state.id] > 0
становится nil > 0
, которое, как я сказал ранее, понимается как вызов метода #>
на nil
. Но вы можете проверить, что NilClass
, к которому принадлежит nil
, не имеет метода экземпляра #>
, определенного на нем:
NilClass.instance_methods.include? :> # => false
nil.respond_to? :> # => false
Исключением NoMethodError
является допустимая ошибка. Поднимая эту ошибку, Ruby защищает вас: она сообщает вам, что ваш @state_turns[ state.id ]
не тот, что вы предполагаете. Таким образом, вы можете исправлять свои ошибки раньше и быть более эффективным программистом. Кроме того, исключения Ruby могут быть спасены с помощью инструкции begin ... rescue ... end
. Исключения Ruby, как правило, очень дружественные и полезные объекты, и вы должны научиться определять свои пользовательские исключения в своих проектах программного обеспечения.
Чтобы расширить это обсуждение немного больше, давайте посмотрим, откуда ваша ошибка. Когда вы пишете выражение типа nil > 10
, которое на самом деле nil.>( 10 )
, Ruby начинает поиск метода #>
в цепочке поиска nil
. Вы можете увидеть цепочку поиска, набрав:
nil.singleton_class.ancestors #=> [NilClass, Object, Kernel, BasicObject]
Метод будет искать в каждом модуле цепочки предков: во-первых, Ruby проверит, существует ли #>
на NilClass
, затем на Object
, затем Kernel
и, наконец, BasicObject
. Если #>
не найден ни в одном из них, Ruby будет продолжен, попробовав методы method_missing
, снова по порядку на всех модулях поисковой цепочки. Если даже method_missing
не обрабатывает сообщение :>
, будет вызвано исключение NoMethodError
. Чтобы продемонстрировать, определите метод #method_missing
в Object
, вставив специальное сообщение, которое появится вместо NoMethodError
:
class Object
def method_missing( name, *args )
puts "There is no method '##{name}' defined on #{self.class}, you dummy!"
end
end
[ 1, 2, 3 ][ 3 ] > 2
#=> There is no method '#>' defined on NilClass, you dummy!
Почему он не говорит, как NullPointerException
В Ruby такого исключения нет. Проверьте класс Ruby Exception
.