Avoiding Ruby Keywords
[ Thanks to flgr for pointing out that class_eval isn’t needed. ]
One of the more annoying things, when writing obfuscated programs in a language, is when you’re forced to use keywords rather than functions or other identifiers which can be renamed or aliased.
Yes, if the language has string eval, you can generally write some kind of simple preprocessor to avoid needing to write them in their original form, but I’ve always felt that was a rather cheap thing to do.
Besides which, I loathe string evals, even more when I’m trying not to obfuscate anything. This can probably be attributed to my long career doing maintainence of TCL programs, where quite literally everything is a string eval, with all the brokenness that entails…
Lately I’ve been turning my attention to producing write-only code in Ruby. There, the unavoidable keywords consist mostly of class, module, def, and end. But are they really so unavoidable?
I think not. Consider:
module Frink
def frumple
puts "Eigenzombie"
end
class Gromzalot
def zork
puts "Zogmorfo"
end
end
class Smesh < Gromzalot
def bleem(a)
puts "Potato #{a}"
end
end
end
You can write a near-equivalent without using any keywords:
Frink = Module::new {
define_method(:frumple) {
puts "Eigenzombie"
}
}
Frink::Gromzalot = Class::new {
define_method(:zork) {
puts "Zogmorfo"
}
}
Frink::Smesh = Class::new(Frink::Gromzalot) {
define_method(:bleem) {|a|
puts "Potato #{a}"
}
}
Staunch metaprogrammers likely won’t blink at this all-too-familiar construct — however! It has the exactly the properties we want…
Nary a pesky keyword, nor blight of string evaluation. Of course, the blocks don’t give you class/module scope for constant names (nor does the module name even exist until you exit the block), so you have to qualify everything and do it all outside. And argument passing is a bit funky, and you have to be careful what you take a closure over with all those blocks.
But everything here is a name you can alias or otherwise redefine at whim!
Isn’t that worth it? A real Ruby program with no identifers longer than a character (once you’ve aliased or wrapped all the builtin bits) — imagine! It’s possible! That world is our world!