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:
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.
source share