Ошибка типа: неверный тип аргумента с оператором Ruby &~
Я пытаюсь сравнить флаги в моем приложении Ruby.
У меня есть этот код:
if self.flag &~ flag == self.flag
return false
Но это не будет работать. Я сузил проблему до этого:
irb(main):020:0> my_user.flag
=> 1
irb(main):021:0> flag
=> 128
irb(main):022:0> my_user.flag.class
=> Fixnum
irb(main):023:0> flag.class
=> Fixnum
irb(main):024:0> my_user.flag &~ flag
TypeError: wrong argument type Fixnum (expected Proc)
Это действительно беспокоит, так как это работает так:
irb(main):025:0> 1 &~ 128
=> 1
1 ответ
Разница между 1 &~ 128
а также my_user.flag &~ flag
является то, что второе выражение включает в себя вызов метода точки. Это меняет способ интерпретации последующих токенов.
Попробуй это:
# works
my_user.flag() &~ flag
# also works
(my_user.flag) &~ flag
# best
my_user.flag & ~flag
Вы обнаружите, что это работает. Это потому что добавление ()
или движется ~
изменяет порядок операций, чтобы он больше соответствовал вашим ожиданиям.
Исходный вызов метода, который вы используете, фактически интерпретируется Ruby как:
# bad
my_user.flag(&(~flag))
Этот порядок операций сначала переворачивает биты в flag
применяя ~
оператор, затем пытается позвонить to_proc
в результате Fixnum
из-за применения &
(приведение-как-блок), а затем, наконец, пытается (если бы не бросил TypeError
) передать его в качестве аргумента блока User#flag
метод.