Ruby Footguns
Author: Alexander Avery
Posted: Sat | Jul 2, 2022
computer-scienceExploring Ruby Metaprogramming Footguns
The last few weeks, I’ve been learning different languages to see what’s popular outside my regular sphere. My journey took me to lots of articles written by Ruby enthusiasts, and the common usage of metaprogramming. Plenty of languages support metaprogramming, but I’ve seen very few communities use and encourage it actively. It’s even used in considerably “Enterprise Projects” such as RSpec and Active Record.
In an effort to have fun with metaprogramming, I’ve created a project of intentional Ruby Footguns. This project is not a point against metaprogramming or meant to showcase potential problems, it is simply meant to make me laugh… or facepalm.
My first entry in this repo is quite basic, a class that implements method_missing
in a rather horrible way.
If you invoke a non-existent method, it will invoke a method with a Levenshtein distance of two or less, and subsequently make it private.
By design, it punishes small typos by causing NoMethodError
to appear from seemingly innocuous lines of code.
class TypoBomb
def print_stuff
puts "My method is working as expected"
end
def method_missing(method_name, *args, &block)
name = methods.select do |name|
levenshtein(name.to_s, method_name.to_s) <= 2
end.first
if !name.nil?
val = send(name, *args, &block)
self.class.undef_method(name)
return val
else
raise NoMethodError
end
end
end
b = TypoBomb.new
b.pint_stuff # > "My method is working as expected"
# more stuff happening until...
b.print_stuff # BOOM! raises NoMethodError and confusion ensues
So now this seemingly perfect line is raising an error, when the real culprit is the typo that occurred elsewhere.
As another consequence, the typo doesn’t even have to occur on the same instance.
If an instance b2
calls print_stoff
, the next time b
or any instance anywhere of TypoBomb
calls print_stuff
, it will break.
Go check out the repo to see this and other footguns complete with unit tests.
Next: Open Source Without GitHub
Previous: Go, One Year Later
>> Home