Помните, (почти) все, что Ruby является объектом ... включая nil
.
Имея это в виду, подумайте, что происходит, когда вы вызываете метод, который не 't существует в nil
:
irb(main):001:0> nil.something
Traceback (most recent call last):
2: from /Users/scott/.rbenv/versions/2.5.1/bin/irb:11:in `<main>'
1: from (irb):1
NoMethodError (undefined method `something' for nil:NilClass)
Кроме того, в Ruby операторы, такие как >
, <
и ==
, фактически являются вызовами методов.Так, например, экземпляр Integer
, такой как 3
, имеет определенный метод, который называется <
, и когда вы вызываете 3 < 4
, он вызывает метод для этого экземпляра.Это работает так, потому что в Ruby вы можете опустить скобки при вызове метода.Например:
irb(main):001:0> 3 < 4
=> true
irb(main):002:0> 3.<(4)
=> true
Итак, соединив эти два примера:
irb(main):014:0> nil < 4
Traceback (most recent call last):
2: from /Users/scott/.rbenv/versions/2.5.1/bin/irb:11:in `<main>'
1: from (irb):14
NoMethodError (undefined method `<' for nil:NilClass)
Теперь давайте посмотрим на ваш код.
Вы получаете исключение:
NoMethodError (undefined method `<' for nil:NilClass)
В этой строке:
!@verified && channel.currency_obj.withdraw_limit < @local_sum
Глядя на этот код, вы звоните только <
в одном месте,Это означает, что все, что слева от него (channel.currency_obj.withdraw_limit
) должно быть nil
.
Есть несколько способов, как мы можем это исправить ... Лучший способ, (по моему мнению), чтобы убедиться, что channel.currency_obj
никогда не может быть nil
.У меня, к сожалению, недостаточно кода, чтобы показать вам, как именно это сделать, поэтому давайте рассмотрим некоторые другие варианты ...
Мы можем использовать Ruby 2.3 + безопасный оператор навигации (&.
) - но это немного странно использовать с таким оператором, как <
.
channel.currency_obj.withdraw_limit&. < @local_sum
Примечание: в этом примере выражение оценивается как nil
и потому что nil
- если false, то условное вернет false.
Или мы можем просто добавить другое выражение в наше условное выражение для проверки на nil
:
!@verified && channel.currency_obj.withdraw_limit && channel.currency_obj.withdraw_limit < @local_sum