Ahh, the hazards of an interpretive language

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.

          -- Pete --

···

--

The address in the header is a Spam Bucket -- don't bother replying to it...
(If you do need to email, replace the account name with my true name.)

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. :slight_smile:

Cheers,
Alvim.

···

On 9/27/06, Pete <neverland@jwgibbs.cchem.berkeley.edu> wrote:

def tt x
  if x == :this
   return "got this"
  elseif x == :that
   return "got that"
  end
  ## ... more actions if neither is true
end

Pete wrote:

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 :wink:

[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 :).

   Robin Stocker

If you run Ruby with the -w command line flag, you will get a warning message about this.

Regards, Morton

···

On Sep 27, 2006, at 1:40 AM, Pete wrote:

def tt x
  if x == :this
   return "got this"
  elseif x == :that
   return "got that"
  end
  ## ... more actions if neither is true
end

Pete wrote:

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

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.

Certainly. :slight_smile:

Kind regards

  robert

In article <4nvv12FcdigrU1@individual.net>,

Pete wrote:

def tt x
  if x == :this
   return "got this"
  elseif x == :that
   return "got that"
  end
  ## ... more actions if neither is true
end

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. :slight_smile:

(:-))
Thanks for the suggestions. My learning curve is ever upward...

          -- Pete --

···

Robert Klemme <shortcutter@googlemail.com> wrote:

--

The address in the header is a Spam Bucket -- don't bother replying to it...
(If you do need to email, replace the account name with my true name.)

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! :slight_smile:

Kind regards

    robert

···

Pete <neverland@jwgibbs.cchem.berkeley.edu> wrote: