Using the ruby_parser and Ruby2Ruby gems, I'm writing code that keeps track of what conditions have been evaluated and what their results and parameters were. In order to keep this as simple as possible, I sometimes rewrite the AST a bit. Of course, I can only do that if I'm sure the result functions exactly the same as the original.
Am I correct in asserting that the following three Ruby snippets are equivalent in function, assuming the triple dots are replaced by a valid Ruby expression? Am I overlooking any edge cases?
case var
when foo
something
when ...
another_thing
else
something_else
end
if foo === var
something
elsif ... === var
another_thing
else
something_else
end
case
when foo === var
something
when ... === var
another_thing
else
something_else
end
Those three snippets are equivalent iff var
is idempotent, i.e. evaluating var
multiple times has the same side-effects as evaluating it once.
So, if var
really is a variable, you are safe, but remember that it can be an arbitrary expression, including a message send to a side-effecting method (like puts
).
E.g.
case puts('Hello')
when 1
when 2
is not the same as
if 1 === puts('Hello')
elsif 2 === puts('Hello')
because in the latter case, "Hello" will be printed twice.
A better translation might be:
__randomly_generated_guaranteed_unique_local_variable_jhggfq45g345 = var
if foo === __randomly_generated_guaranteed_unique_local_variable_jhggfq45g345
something
elsif ... === __randomly_generated_guaranteed_unique_local_variable_jhggfq45g345
another_thing
else
something_else
end
case
when foo === __randomly_generated_guaranteed_unique_local_variable_jhggfq45g345
something
when ... === __randomly_generated_guaranteed_unique_local_variable_jhggfq45g345
another_thing
else
something_else
end