This sort of thing has most probably been noted and reported by other
people before, but as a relative newcomer to ruby I found it amusing…
At a point in the code I was writing I found I wanted an ‘alternative
if’,
so I glanced at the quick-reference and wrote something like this (the
actual code being more useful, of course):
def tt x
if x == :this
return “got this”
elseif x == :that
return “got that”
end
… more actions if neither is true
end
and was totally flummoxed for half an hour or so because the second
{’:that’) action was never being executed! No error messages, ever,
so I figured the syntax must be OK… (:-/) [Ruby up to that point
had been superb at identifying errors.]
Then I finally went and re-read the docs a little more carefully…!
My typo in ‘elsif’ was of course never being caught because execution
never reached it. (If I replace the ‘return’ with a non-exiting
statement,
the error shows up at once, of course.)
[The experience inspired me to see how the construct is handled in
other languages. None of them seem to agree here! (C family: “else
if”;
Python: “elif”, Algol: “ELSF”…) And only my old idol Pop-11 [WHO?!]
actually uses “elseif”.]
Oh well. At least it’s the sort of slip one doesn’t repeat.
def tt x
if x == :this
return “got this”
elseif x == :that
return “got that”
end
… more actions if neither is true
end
I’ve never fallen into that trap but, as a complete newbie to Ruby, I
was bound to, sooner or later. The problem is, even after reading your
code and explanation, I wasn’t able to really ‘get’ what was
happening. So I fired up irb, did some testing and finally understood.
So, for the sake of other newbies like me, I’ll post a code that is
similar to yours, with little ‘didatic’ changes. I know it’s just what
you were trying to explain, I’m only putting it another way in order
to (hopefully) help someone who, like me, couldn’t ‘get it’ the first
time:
def tt(x)
if x == :this
return “got this”
zoinks #notice how the interpreter doesn’t
zinks #care about these lines
return “got that” #neither does he care about this one
end
return “got something else”
end
So:
tt(:this) #=> “got this”
tt(:anything_else) #=> “got something else”
Thanks, Pete, for bringing that up. I’m sure I’d fall into this one at
some point.
My typo in ‘elsif’ was of course never being caught because execution
never reached it. (If I replace the ‘return’ with a non-exiting statement,
the error shows up at once, of course.)
Maybe an editor with syntax highlighting would help with this kind of
typo. But you are right, you won’t make this mistake again
[The experience inspired me to see how the construct is handled in
other languages. None of them seem to agree here! (C family: “else if”;
Python: “elif”, Algol: “ELSF”…) And only my old idol Pop-11 [WHO?!]
actually uses “elseif”.]
Perl also uses “elsif”. This is one of the good things Ruby inherited
from Perl if you ask me :).
Btw, the typical solution in Ruby would be to use a Hash. Then tt will
boil down to “def tt(x) your_hash[x] end”. The next best solution (and
also more similar to what you did) is a case statement
def tt x
case x
when :this then “got this”
when :that then “got that”
else “foo”
end
end
Note: semantics are not identical since this case statement uses “===”
for evaluation of cases. If you want identical behavior you can use
case
when x == :this then “got this”
…
end
and was totally flummoxed for half an hour or so because the second
{’:that’) action was never being executed! No error messages, ever,
so I figured the syntax must be OK… (:-/) [Ruby up to that point
had been superb at identifying errors.]
Well, the syntax is ok.
Oh well. At least it’s the sort of slip one doesn’t repeat.
Btw, the typical solution in Ruby would be to use a Hash. Then tt will
boil down to “def tt(x) your_hash[x] end”. The next best solution (and
also more similar to what you did) is a case statement
Yes, of course, but the actual actions were rather more complex than
just returning a value. That was just for illustration…
I could (and probably eventually would) have used a case, as there were
several other possible flag values, but code evolves, y’know… (:-))
Oh well. At least it’s the sort of slip one doesn’t repeat.
Certainly.
(:-))
Thanks for the suggestions. My learning curve is ever upward…
Btw, the typical solution in Ruby would be to use a Hash. Then tt
will boil down to “def tt(x) your_hash[x] end”. The next best
solution (and also more similar to what you did) is a case statement
Yes, of course, but the actual actions were rather more complex than
just returning a value. That was just for illustration…
In that case you could even put lambdas in the Hash and execute them:
def tt(x) code[x][] end
I could (and probably eventually would) have used a case, as there
were several other possible flag values, but code evolves, y’know…
(:-))
Refactor, refactor, refactor!
Kind regards
robert
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.