Sneak Peek: Unhygienic Rewriting Ruby by Example
def test_unhygienic_andand
andand = Unhygienic.from {
__to_receiver.andand.__to_message(__splat_parameters)
}.to {
lambda { |andand_temp|
andand_temp.__to_message(__splat_parameters) if andand_temp
}.call(__to_receiver)
}
assert_equal(
'Hello' + ' World',
with(andand) do
'Hello'.andand + ' World'
end
)
assert_nil(
with(andand) do
nil.andand + ' World'
end
)
end
Let’s take a closer look:
Rewrite::With.expand(andand) do
class Funky
def hello_world
'Hello'.andand + ' World'
end
end
end
produces:
class Funky
def hello_world
lambda { |andand_temp|
(andand_temp + " World") if andand_temp
}.call("Hello")
end
end
As you can probably deduce, it’s
unhygienic: Variables like andand_temp shadow variables declared elsewhere. This is a problem if you fail to choose a sufficiently obfuscated name or—more likely—nest constructions like #andand.
Both the
Classically Metaprogrammed and the
Sexp-Rewriting versions of #andand avoid this problem.
Next step: Better hygiene.