Case when

In all examples I can see in my book about 'case ..' 'when..' 'then.. '
there is only one statement after the 'when..' I understand using 'then' if the statement is on the same line as 'when', BUT
can I write multiple statements after the 'when' ?

like that :

case 'a'
  when 'a1'
    puts..
    puts ...
  return
  when 'a2'
    puts ...
  return
  when 'a3' then puts ...
  else
    puts ...
    puts ...
end

thansk fyh

Josselin wrote:

In all examples I can see in my book about 'case ..' 'when..' 'then.. '
there is only one statement after the 'when..' I understand using 'then' if the statement is on the same line as 'when', BUT
can I write multiple statements after the 'when' ?

like that :

case 'a'
    when 'a1'
        puts..
        puts ...
    return
    when 'a2'
        puts ...
    return
    when 'a3' then puts ...
    else
        puts ...
        puts ...
end

Try it!

···

--

a return was missing to close the latest 'else'....

got it...

···

On 2007-01-05 16:07:15 +0100, Carlos <angus@quovadis.com.ar> said:

Josselin wrote:

In all examples I can see in my book about 'case ..' 'when..' 'then.. '
there is only one statement after the 'when..' I understand using 'then' if the statement is on the same line as 'when', BUT
can I write multiple statements after the 'when' ?

like that :

case 'a'
    when 'a1'
        puts..
        puts ...
    return
    when 'a2'
        puts ...
    return
    when 'a3' then puts ...
    else
        puts ...
        puts ...
end

Try it!

Huh? You don't need returns to "close" the when's or else. Unlike C,
there's no "trickle" effect to Ruby case statements, one a branch has
been matched, only that branch is executed. There's no need for
"break" or "return" or anything like that.

Jacob Fugal

···

On 1/5/07, Josselin <josselin@wanadoo.fr> wrote:

>> case 'a'
>> when 'a1'
>> puts..
>> puts ...
>> return
>> when 'a2'
>> puts ...
>> return
>> when 'a3' then puts ...
>> else
>> puts ...
>> puts ...
>> end

a return was missing to close the latest 'else'....

Personally I like to adopt the old Smalltalk philosophy, where they
don't even use case statements. Since over time these can grow long and
ungainly you can take a different programming approach. It's a bit of a
mind stretch depending on where you're coming from, but it is good
practice. I think there's an older book called Smalltalk Best Practice
Patterns that touches on this. A good read, even if you don't ever
write a lick of Smalltalk. It's solid OOP approaches you can apply to
Ruby and other OOP languages.

Jacob Fugal wrote:

···

On 1/5/07, Josselin <josselin@wanadoo.fr> wrote:
> >> case 'a'
> >> when 'a1'
> >> puts..
> >> puts ...
> >> return
> >> when 'a2'
> >> puts ...
> >> puts ...
> >> puts ...
> >> return
> >> when 'a3' then puts ...
> >> else
> >> puts ...
> >> puts ...
> >> end
>
> a return was missing to close the latest 'else'....

Huh? You don't need returns to "close" the when's or else. Unlike C,
there's no "trickle" effect to Ruby case statements, one a branch has
been matched, only that branch is executed. There's no need for
"break" or "return" or anything like that.

Jacob Fugal

It's also a "code smell" according to the classic Refactoring text:

http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html

James Edward Gray II

···

On Jan 5, 2007, at 11:10 AM, gregarican wrote:

Personally I like to adopt the old Smalltalk philosophy, where they
don't even use case statements. Since over time these can grow long and
ungainly you can take a different programming approach. It's a bit of a
mind stretch depending on where you're coming from, but it is good
practice. I think there's an older book called Smalltalk Best Practice
Patterns that touches on this.

Good point. All of it makes for good mental exercise and ultimately
more effective and efficient development. Rather than run something
through a bunch of conditionals, just pass along an overridden message
like 'processYourself' and let the object do the work. Depending on
what the object is receiving the message it can choose its own way of
doing things.

James Edward Gray II wrote:

···

On Jan 5, 2007, at 11:10 AM, gregarican wrote:

> Personally I like to adopt the old Smalltalk philosophy, where they
> don't even use case statements. Since over time these can grow long
> and
> ungainly you can take a different programming approach. It's a bit
> of a
> mind stretch depending on where you're coming from, but it is good
> practice. I think there's an older book called Smalltalk Best Practice
> Patterns that touches on this.

It's also a "code smell" according to the classic Refactoring text:

Catalog of Refactorings
replaceConditionalWithPolymorphism.html

James Edward Gray II

thanks a lot for the link... I'll read taht tonight !

I have to understand how to avoid 'if.. ' and 'case..' to check mulitple 'submit buttons from my form...

I have an account_controller object .. when the user 'submit the form, the 'confirm' method is called, but 2 buttons can confirm
so I have to check upon the submit value... which I do
each submit button CANNOT call a different method in my object..
...
I understand your concerns with OO programming approach, but who can illustrate this approach on such simple problem...

joss

···

On 2007-01-05 18:25:03 +0100, "gregarican" <greg.kujawa@gmail.com> said:

Good point. All of it makes for good mental exercise and ultimately
more effective and efficient development. Rather than run something
through a bunch of conditionals, just pass along an overridden message
like 'processYourself' and let the object do the work. Depending on
what the object is receiving the message it can choose its own way of
doing things.

James Edward Gray II wrote:

On Jan 5, 2007, at 11:10 AM, gregarican wrote:

Personally I like to adopt the old Smalltalk philosophy, where they
don't even use case statements. Since over time these can grow long
and
ungainly you can take a different programming approach. It's a bit
of a
mind stretch depending on where you're coming from, but it is good
practice. I think there's an older book called Smalltalk Best Practice
Patterns that touches on this.

It's also a "code smell" according to the classic Refactoring text:

Catalog of Refactorings
replaceConditionalWithPolymorphism.html

James Edward Gray II

Are you sure about that? :wink:

class AccountController < ApplicationController
   # ...

   def confirm
     send("confirm_for_#{params[:submit_button]}")
   end

   # ...

   private

   def confirm_for_button_one_name
     # ... whatever ...
   end

   def confirm_for_button_two_name
     # ... whatever ...
   end

   # ...
end

Just a thought. Not that there is anything wrong with your case statement though.

James Edward Gray II

···

On Jan 5, 2007, at 11:40 AM, Josselin wrote:

I have an account_controller object .. when the user 'submit the form, the 'confirm' method is called, but 2 buttons can confirm
so I have to check upon the submit value... which I do
each submit button CANNOT call a different method in my object..

I wanted to write that this is not a good example -- the case
statement would be more readable and probably even faster. Then I
realized that the situation changes if somebody wants to subclass this
and add another button. Just add another method and it's done. With
the case statement it wouldn't be that easy.

Then I was thinking that if the params[:submit_button] contained the
whole method name, the confim method would be nicer. The drawback is
that the way it is now provides a bit of security -- it's not
possible to call any method, just a limited subset. It would be
possible to check whether the param is in a specified set, but that
would break extensibility (or a means to extend the set would be
needed).

···

On 1/5/07, James Edward Gray II <james@grayproductions.net> wrote:

On Jan 5, 2007, at 11:40 AM, Josselin wrote:

> I have an account_controller object .. when the user 'submit the
> form, the 'confirm' method is called, but 2 buttons can confirm
> so I have to check upon the submit value... which I do
> each submit button CANNOT call a different method in my object..

Are you sure about that? :wink:

class AccountController < ApplicationController
   # ...

   def confirm
     send("confirm_for_#{params[:submit_button]}")
   end

   # ...

   private

   def confirm_for_button_one_name
     # ... whatever ...
   end

   def confirm_for_button_two_name
     # ... whatever ...
   end

   # ...
end

Just a thought. Not that there is anything wrong with your case
statement though.

James Edward Gray II

It's just one thought. There are times when it is very powerful (like when building state machines), but this probably isn't one of them and there is nothing wrong with using a case statement here, in my opinion.

James Edward Gray II

···

On Jan 5, 2007, at 3:49 PM, Jan Svitok wrote:

On 1/5/07, James Edward Gray II <james@grayproductions.net> wrote:

On Jan 5, 2007, at 11:40 AM, Josselin wrote:

> I have an account_controller object .. when the user 'submit the
> form, the 'confirm' method is called, but 2 buttons can confirm
> so I have to check upon the submit value... which I do
> each submit button CANNOT call a different method in my object..

Are you sure about that? :wink:

class AccountController < ApplicationController
   # ...

   def confirm
     send("confirm_for_#{params[:submit_button]}")
   end

   # ...

   private

   def confirm_for_button_one_name
     # ... whatever ...
   end

   def confirm_for_button_two_name
     # ... whatever ...
   end

   # ...
end

Just a thought. Not that there is anything wrong with your case
statement though.

James Edward Gray II

I wanted to write that this is not a good example -- the case
statement would be more readable and probably even faster. Then I
realized that the situation changes if somebody wants to subclass this
and add another button. Just add another method and it's done. With
the case statement it wouldn't be that easy.

Then I was thinking that if the params[:submit_button] contained the
whole method name, the confim method would be nicer. The drawback is
that the way it is now provides a bit of security -- it's not
possible to call any method, just a limited subset. It would be
possible to check whether the param is in a specified set, but that
would break extensibility (or a means to extend the set would be
needed).