How to "break" a "case-when"?

Hi, is not possible to terminate the body of a “when” stament?

I mean:

case num
when 1:
puts “Is 1 !!!”
break
puts “Don’t write it”
end

puts “Write it”

but unfortunatelly the “break” gives an error.

Thanks for any suggestion.

From: Iñaki Baz C. [mailto:[email protected]]

Hi, is not possible to terminate the body of a “when” stament?

case num

when 1:

puts “Is 1 !!!”

break

puts “Don’t write it”

end

puts “Write it”

afaik, no. but why would you want to do that? are you porting c codes?

kind regards -botp

2008/4/17, Iñaki Baz C. [email protected]:

puts “Write it”

but unfortunatelly the “break” gives an error.

break is only for iteration. What are you trying to do?
The example you’ve given is not a compelling use case,
since you can simply remove the line after break.

Also, Ruby’s case/when doesn’t fall through when clauses.

case 1
when 1
  puts "it's 1"
when 2
  puts "this is not printed"
end

Stefan

2008/4/17, Stefan L. [email protected]:

break is only for iteration. What are you trying to do?
The example you’ve given is not a compelling use case,
since you can simply remove the line after break.

Ok, I write a better example:

var = …something…

case num
when 1:
puts “var not valid !!!” if ( var < 0 || var > 10 )
break
do_normal_stuff


end_normal_stuff
end

puts “Write it”

I just want do_normal_stuff in case “var” is valid.
Yes, I can put a big “if” stament and so but I would like not to do it
since it makes a bit ugly the code.

2008/4/17, Peter H. [email protected]:

But in this example the code between do_normal_stuff and end_normal_stuff
would never be executed, not even in C!

Opss, sorry, my mistake. This would be:

var = …something…

case num
when 1:
if ( var < 0 || var > 10 )
puts “var not valid !!!”
break
end
do_normal_stuff


end_normal_stuff
end

puts “Write it”

end
Yes, but what I was trying to avoid is to enclose all the “real” stuff
ni a “if” stament since it’s in fact the default behaviour and that
will be executed 99% of times.

Anyway I understand that is the only way.

Thanks a lot for all. :slight_smile:

Iñaki Baz C. wrote:

end

puts “Write it”

I just want do_normal_stuff in case “var” is valid.
Yes, I can put a big “if” stament and so but I would like not to do it
since it makes a bit ugly the code.

But in this example the code between do_normal_stuff and
end_normal_stuff would never be executed, not even in C!

Why not write something simpler

case num
when 1:
if 0 <= var and var <= 10) then
do_normal_stuff


end_normal_stuff
puts “Write it”
end

I think you are trying to be too clever here. Stick to the simple stuff.

2008/4/17, Stefan L. [email protected]:

But be careful, catch/throw is dynamically scoped.
“ri catch” has more info.

thanks for that info :wink:

2008/4/17, Iñaki Baz C. [email protected]:

end

puts “Write it”

I just want do_normal_stuff in case “var” is valid.
Yes, I can put a big “if” stament and so but I would like not to do it
since it makes a bit ugly the code.

Well, since Ruby doesn’t support it, you must find other
ways to structure the code in each case. Exceptions might
help in the bigger picture, splitting it up in smaller methods, etc.

You can use catch/throw for this:

catch(:invalid_var) {
  case num
  when 1
    if var < 0 || var > 10
      puts "var not valid !!!!!"
      throw(:invalid_var)
    end
    do_normal_stuff
    ...
    ...
    end_normal_stuff
  end
}
puts "Write it"

But be careful, catch/throw is dynamically scoped.
“ri catch” has more info.

Stefan

2008/4/17, Stefan L. [email protected]:

2008/4/17, Iñaki Baz C. [email protected]:

2008/4/17, Stefan L. [email protected]:

Well, since Ruby doesn’t support it, you must find other
ways to structure the code in each case. Exceptions might
help in the bigger picture, splitting it up in smaller methods, etc.

You can use catch/throw for this:

I would recommend using an “ordinary” exception - because that’s what it
is.

var = …something…

case num
when 1:
raise “var invalid!” if var < 0 || var > 10
do_normal_stuff


end_normal_stuff
end

puts “Write it”

Kind regards

robert

El Viernes, 18 de Abril de 2008, Peña, Botp escribió:

else_stuff

end
puts “Write it”

opss, I didn’t know that a “when” can contain a comparision, nice to
know!

Thanks.

On Thu, Apr 17, 2008 at 4:14 PM, Robert K.
[email protected] wrote:

You can use catch/throw for this:

I would recommend using an “ordinary” exception - because that’s what it is.
I would recommend not to use an exception at all.

If I had the problem I would try to the following things in that order:
(a) restructure your case if this makes it more readable
(b) if not a local exit might make the code quite readable,
if the case is used in a loop that well be “next”, if the case is
a method body, which is often the case use “return”
(c) if neither (a) or (b) provide some appealing code, try to refactor
the case into a method
(d) and only if (c) makes no sense either use
catch(:mylocalexit){
case…
throw :mylocalexit
}

HTH
Robert


http://ruby-smalltalk.blogspot.com/


Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

From: Iñaki Baz C. [mailto:[email protected]]

var = …something…

case num

when 1:

if ( var < 0 || var > 10 )

puts “var not valid !!!”

break

end

do_normal_stuff

end_normal_stuff

end

puts “Write it”

#…

Yes, but what I was trying to avoid is to enclose all the “real” stuff

ni a “if” stament since it’s in fact the default behaviour and that

will be executed 99% of times.

Anyway I understand that is the only way.

how about another case way,

var = …something…
case
when num==1 and ( var < 0 || var > 10 )
puts “var not valid for num==1 !!!”
when other_stuff_condition
when …

else
else_stuff
end
puts “Write it”

kind regards -botp

On Fri, Apr 18, 2008 at 8:52 PM, Iñaki Baz C. [email protected] wrote:

 ...

else
else_stuff
end
puts “Write it”

opss, I didn’t know that a “when” can contain a comparision, nice to know!
It can contain any expression, but it will not do what you want.
The semantics of case is the following

case e
when e1
a1
when e2
a2
else
a3
end

if e1 === e then
a1
elsif e2 === e then
a2
else
a3
end

unfortunately
case e
when true
a

will only work for e == true as
true === Object.new → false

maybe Matz did not want to allow logical comparision in case :wink:

but he gave us the power to overrule

try the following code with the line commented and then uncommented and
you will see what is going on

class TrueClass

def === any; true end

end

case 42
when true
p true
else
p :else
end
HTH
R.

http://ruby-smalltalk.blogspot.com/


Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

El Viernes, 18 de Abril de 2008, Robert D.
escribió:

else
p :else
end

Interesting, nice to know :slight_smile:

On Fri, Apr 18, 2008 at 1:40 PM, Robert D. [email protected]
wrote:

when other_stuff_condition
when …

else
else_stuff
end
puts “Write it”

opss, I didn’t know that a “when” can contain a comparision, nice to know!
It can contain any expression, but it will not do what you want.

Sure it will. There are two different forms of case, the form
case
when foo1 then bar1
when foo2 then bar2

else baz
end

Works exactly as described above.

You could do it with the other kind of case (the one whose semantics
you describe),
but it would be a bit uglier. E.g.,

case num
when (if var.between? 0, 10 then 1 else Object.new) then
do_normal_stuff
when 1 then do_error_stuff

end

On Sat, Apr 19, 2008 at 7:59 PM, Christopher D. [email protected]
wrote:

 puts "var not valid for num==1 !!!!!"

Sure it will. There are two different forms of case, the form
First my appologies for my error, I did not see that the case part was
empty, my fault
you describe),
but it would be a bit uglier. E.g.,

case num
when (if var.between? 0, 10 then 1 else Object.new) then do_normal_stuff
when 1 then do_error_stuff

end

my point is however that of course you lose the basic feature you
wanted but we have two possibilities here, either monkeypatching
TrueClass and using the !! form to convert any logical true value to
the real single true value, than the code might look like this

case expression
when /abc/

when !! get_an_object(expression)

I have to admit that the monkey patch is just not an option if you are
writing a library and is a feature too often abused anyway.

I therefore suggest to follow Christopher’s approach even if the code
gets a little bit uglier (but beauty lies in the eyes of the
beholder).

case
when /abc/ === expression

when get_an_object( expression )

end

Sorry again, I outsmarted myself :wink:

Cheers
Robert


http://ruby-smalltalk.blogspot.com/


Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein