Ошибка типа: неверный тип аргумента с оператором 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 метод.

Другие вопросы по тегам