TypeError: invalid argument type with Ruby operator & ~

I am trying to compare flags in my Ruby application.

I have this code:

if self.flag &~ flag == self.flag return false 

But it will not work. I narrowed down the problem:

 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) 

This is really worrying, as it works as follows:

 irb(main):025:0> 1 &~ 128 => 1 
+4
source share
1 answer

The difference between 1 &~ 128 and my_user.flag &~ flag is that the second expression involves calling the dot method. This changes the way that subsequent tokens are interpreted.

Try the following:

 # works my_user.flag() &~ flag # also works (my_user.flag) &~ flag # best my_user.flag & ~flag 

You will find that it works. This is because adding () or moving ~ changes the order of operations as expected.

The original call to the method you use is actually interpreted by Ruby as:

 # bad my_user.flag(&(~flag)) 

This order of operations first flips the bits into flag using the ~ operator, then tries to call to_proc in the resulting Fixnum due to the use of & (cast-as-block), and then finally tries (if it didn't select TypeError ) to pass it as a block argument to the User#flag method.

+4
source

All Articles