In Ruby, negation is a method
Posted by matijs 30/01/2014 at 06h16
These past few days, I’ve been busy updating RipperRubyParser to make it compatible with RubyParser 3. This morning, I discovered that one thing that was changed from RubyParser 2 is the parsing of negations.
Before, !foo
was parsed like this:
s(:not, s(:call, nil, :foo))
Now, !foo
is parsed like this:
s(:call, s(:call, nil, :foo), :!)
That looks a lot like a method call. Could it be that in fact, it is a method call? Let’s see.
foo = Object.new
def foo.!
puts "Negating …"
false
end
!foo # prints: Negating …
# => false
Amazing. Negation is a method call! Does this mean I can make it return something insane?
def foo.!
"Not really not"
end
!foo # => "Not really not"
Yes!
Now what can you do with this? At first sight, this may look pretty crazy and useless. But perhaps you can make a string class where !"true" == "false"
, or code to handle boolean values codified as strings in a database. This is just another part where Ruby is a lot more flexible than you might at first think.