Assume these methods:
def aa x; [:aa, x] end
def bb x=0; [:bb, x] end
Now let's try this expression:
aa bb %(1) #=> [:aa, [:bb, "1"]]
Ok, so far, so good. 'aa bb %(1)' parses as two methods and a string.
That is, like this: aa(bb("1"))
But, what if there's also a variable called aa?
aa=nil
aa bb %(1) #=> NoMethodError: undefined method `%' for [:bb, 0]:Array
The same expression is parsing differently. The % sign is now an
operator, not the start of a string. It's now parsing like this:
aa(bb() % 1)
Normally, these ambiguous cases are covered by a simple rule: whitespace
before and not after the ambigious character forces it to be not
considered an operator. That makes sense to me. That's the way the
expression parsed before a variable was defined. A variable name
preceding the ambiguous char would also force an operator to be found,
but that's not the case here; bb is a method. What precedes bb shouldn't
matter, or so I would think. (And its a method too, anyway.) It's as if
the fact that the call to aa _could_ have been a variable, even though
it wasn't, (because it clearly has a param list) forces a distant % sign
to be treated differently. Spooky action at a distance.
Note that the ambiguous ident need not be so close to the operator it
modifies:
aa=nil
aa bb bb bb bb bb bb bb bb bb bb %(1)
#=> NoMethodError: undefined method `%' for [:bb, 0]:Array
I'm not sure if this is a bug or not, but it sure seems strange to me if
it isn't.
This was seen with ruby 1.9.0-4 and 1.8.7-p72, as well as earlier versions.