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

  • Thread starter Iñaki Baz Castillo
  • Start date
I

Iñaki Baz Castillo

SGksIGlzIG5vdCBwb3NzaWJsZSB0byB0ZXJtaW5hdGUgdGhlIGJvZHkgb2YgYSAid2hlbiIgc3Rh
bWVudD8KCkkgbWVhbjoKCiAgY2FzZSBudW0KICB3aGVuIDE6CiAgICBwdXRzICJJcyAxICEhISEi
CiAgICBicmVhawogICAgcHV0cyAiRG9uJ3Qgd3JpdGUgaXQiCiAgZW5kCgogIHB1dHMgIldyaXRl
IGl0IgoKYnV0IHVuZm9ydHVuYXRlbGx5IHRoZSAiYnJlYWsiIGdpdmVzIGFuIGVycm9yLgoKVGhh
bmtzIGZvciBhbnkgc3VnZ2VzdGlvbi4KCi0tIApJw7Fha2kgQmF6IENhc3RpbGxvCjxpYmNAYWxp
YXgubmV0Pgo=
 
P

Peña, Botp

RnJvbTogScOxYWtpIEJheiBDYXN0aWxsbyBbbWFpbHRvOmliY0BhbGlheC5uZXRdIA0KIyBIaSwg
aXMgbm90IHBvc3NpYmxlIHRvIHRlcm1pbmF0ZSB0aGUgYm9keSBvZiBhICJ3aGVuIiBzdGFtZW50
Pw0KIyAgIGNhc2UgbnVtDQojICAgd2hlbiAxOg0KIyAgICAgcHV0cyAiSXMgMSAhISEhIg0KIyAg
ICAgYnJlYWsNCiMgICAgIHB1dHMgIkRvbid0IHdyaXRlIGl0Ig0KIyAgIGVuZA0KIyAgIHB1dHMg
IldyaXRlIGl0Ig0KDQphZmFpaywgbm8uIGJ1dCB3aHkgd291bGQgeW91IHdhbnQgdG8gZG8gdGhh
dD8gYXJlIHlvdSBwb3J0aW5nIGMgY29kZXM/DQoNCmtpbmQgcmVnYXJkcyAtYm90cA0K
 
S

Stefan Lang

2008/4/17 said:
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.

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
 
I

Iñaki Baz Castillo

MjAwOC80LzE3LCBTdGVmYW4gTGFuZyA8cGVyZmVjdGx5Lm5vcm1hbC5oYWNrZXJAZ21haWwuY29t
PjoKCj4gYnJlYWsgaXMgb25seSBmb3IgaXRlcmF0aW9uLiBXaGF0IGFyZSB5b3UgdHJ5aW5nIHRv
IGRvPwo+ICBUaGUgZXhhbXBsZSB5b3UndmUgZ2l2ZW4gaXMgbm90IGEgY29tcGVsbGluZyB1c2Ug
Y2FzZSwKPiAgc2luY2UgeW91IGNhbiBzaW1wbHkgcmVtb3ZlIHRoZSBsaW5lIGFmdGVyIGJyZWFr
LgoKT2ssIEkgd3JpdGUgYSBiZXR0ZXIgZXhhbXBsZToKCgogIHZhciA9IC4uLnNvbWV0aGluZy4u
LgoKIGNhc2UgbnVtCiAgd2hlbiAxOgogICAgcHV0cyAidmFyIG5vdCB2YWxpZCAhISEhISIgaWYg
KCB2YXIgPCAwIHx8IHZhciA+IDEwICkKICAgIGJyZWFrCiAgICBkb19ub3JtYWxfc3R1ZmYKICAg
IC4uLgogICAgLi4uCiAgICBlbmRfbm9ybWFsX3N0dWZmCiAgZW5kCgogIHB1dHMgIldyaXRlIGl0
IgoKCkkganVzdCB3YW50IGRvX25vcm1hbF9zdHVmZiBpbiBjYXNlICJ2YXIiIGlzIHZhbGlkLgpZ
ZXMsIEkgY2FuIHB1dCBhIGJpZyAiaWYiIHN0YW1lbnQgYW5kIHNvIGJ1dCBJIHdvdWxkIGxpa2Ug
bm90IHRvIGRvIGl0CnNpbmNlIGl0IG1ha2VzIGEgYml0IHVnbHkgdGhlIGNvZGUuCgoKLS0gCknD
sWFraSBCYXogQ2FzdGlsbG8KPGliY0BhbGlheC5uZXQ+Cg==
 
P

Peter Hickman

Iñaki Baz Castillo said:
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.

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.
 
I

Iñaki Baz Castillo

MjAwOC80LzE3LCBQZXRlciBIaWNrbWFuIDxwZXRlckBzZW1hbnRpY28uY29tPjoKCj4gIEJ1dCBp
biB0aGlzIGV4YW1wbGUgdGhlIGNvZGUgYmV0d2VlbiBkb19ub3JtYWxfc3R1ZmYgYW5kIGVuZF9u
b3JtYWxfc3R1ZmYKPiB3b3VsZCBuZXZlciBiZSBleGVjdXRlZCwgbm90IGV2ZW4gaW4gQyEKCk9w
c3MsIHNvcnJ5LCBteSBtaXN0YWtlLiBUaGlzIHdvdWxkIGJlOgoKdmFyID0gLi4uc29tZXRoaW5n
Li4uCgogIGNhc2UgbnVtCiAgd2hlbiAxOgogICAgaWYgKCB2YXIgPCAwIHx8IHZhciA+IDEwICkK
ICAgICAgICBwdXRzICJ2YXIgbm90IHZhbGlkICEhISEhIgogICAgICAgIGJyZWFrCiAgICBlbmQK
ICAgIGRvX25vcm1hbF9zdHVmZgogICAgLi4uCiAgICAuLi4KICAgIGVuZF9ub3JtYWxfc3R1ZmYK
ICBlbmQKCiAgcHV0cyAiV3JpdGUgaXQiCgoKCj4gIFdoeSBub3Qgd3JpdGUgc29tZXRoaW5nIHNp
bXBsZXIKPgo+ICBjYXNlIG51bQo+ICB3aGVuIDE6Cj4gICBpZiAwIDw9IHZhciBhbmQgdmFyIDw9
IDEwKSB0aGVuCj4gICAgZG9fbm9ybWFsX3N0dWZmCj4gICAgLi4uCj4gICAgLi4uCj4gICAgZW5k
X25vcm1hbF9zdHVmZgo+ICAgIHB1dHMgIldyaXRlIGl0Igo+ICAgZW5kCgpZZXMsIGJ1dCB3aGF0
IEkgd2FzIHRyeWluZyB0byBhdm9pZCBpcyB0byBlbmNsb3NlIGFsbCB0aGUgInJlYWwiIHN0dWZm
Cm5pIGEgImlmIiBzdGFtZW50IHNpbmNlIGl0J3MgaW4gZmFjdCB0aGUgZGVmYXVsdCBiZWhhdmlv
dXIgYW5kIHRoYXQKd2lsbCBiZSBleGVjdXRlZCA5OSUgb2YgdGltZXMuCgpBbnl3YXkgSSB1bmRl
cnN0YW5kIHRoYXQgaXMgdGhlIG9ubHkgd2F5LgoKVGhhbmtzIGEgbG90IGZvciBhbGwuIDopCgoK
LS0gCknDsWFraSBCYXogQ2FzdGlsbG8KPGliY0BhbGlheC5uZXQ+Cg==
 
S

Stefan Lang

2008/4/17 said:
Ok, I write a better example:


var =3D ...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.

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
 
I

Iñaki Baz Castillo

MjAwOC80LzE3LCBTdGVmYW4gTGFuZyA8cGVyZmVjdGx5Lm5vcm1hbC5oYWNrZXJAZ21haWwuY29t
PjoKPiBCdXQgYmUgY2FyZWZ1bCwgY2F0Y2gvdGhyb3cgaXMgZHluYW1pY2FsbHkgc2NvcGVkLgo+
ICAicmkgY2F0Y2giIGhhcyBtb3JlIGluZm8uCgp0aGFua3MgZm9yIHRoYXQgaW5mbyA7KQoKLS0g
CknDsWFraSBCYXogQ2FzdGlsbG8KPGliY0BhbGlheC5uZXQ+Cg==
 
R

Robert Klemme

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=
 
P

Peña, Botp

RnJvbTogScOxYWtpIEJheiBDYXN0aWxsbyBbbWFpbHRvOmliY0BhbGlheC5uZXRdIA0KIyB2YXIg
PSAuLi5zb21ldGhpbmcuLi4NCiMgICBjYXNlIG51bQ0KIyAgIHdoZW4gMToNCiMgICAgIGlmICgg
dmFyIDwgMCB8fCB2YXIgPiAxMCApDQojICAgICAgICAgcHV0cyAidmFyIG5vdCB2YWxpZCAhISEh
ISINCiMgICAgICAgICBicmVhaw0KIyAgICAgZW5kDQojICAgICBkb19ub3JtYWxfc3R1ZmYNCiMg
ICAgIC4uLg0KIyAgICAgLi4uDQojICAgICBlbmRfbm9ybWFsX3N0dWZmDQojICAgZW5kDQojICAg
cHV0cyAiV3JpdGUgaXQiDQojLi4uLg0KIyBZZXMsIGJ1dCB3aGF0IEkgd2FzIHRyeWluZyB0byBh
dm9pZCBpcyB0byBlbmNsb3NlIGFsbCB0aGUgInJlYWwiIHN0dWZmDQojIG5pIGEgImlmIiBzdGFt
ZW50IHNpbmNlIGl0J3MgaW4gZmFjdCB0aGUgZGVmYXVsdCBiZWhhdmlvdXIgYW5kIHRoYXQNCiMg
d2lsbCBiZSBleGVjdXRlZCA5OSUgb2YgdGltZXMuDQojIEFueXdheSBJIHVuZGVyc3RhbmQgdGhh
dCBpcyB0aGUgb25seSB3YXkuDQoNCmhvdyBhYm91dCBhbm90aGVyIGNhc2Ugd2F5LCANCg0KdmFy
ID0gLi4uc29tZXRoaW5nLi4uDQpjYXNlIA0KICB3aGVuIG51bT09MSBhbmQgKCB2YXIgPCAwIHx8
IHZhciA+IDEwICkNCiAgICAgcHV0cyAidmFyIG5vdCB2YWxpZCBmb3IgbnVtPT0xICEhISEhIg0K
ICB3aGVuIG90aGVyX3N0dWZmX2NvbmRpdGlvbg0KICB3aGVuIC4uLi4NCiAgICAgLi4uDQogIGVs
c2UNCiAgICBlbHNlX3N0dWZmDQplbmQNCnB1dHMgIldyaXRlIGl0Ig0KDQpraW5kIHJlZ2FyZHMg
LWJvdHANCg==
 
I

Iñaki Baz Castillo

El Viernes, 18 de Abril de 2008, Pe=C3=B1a, Botp escribi=C3=B3:
how about another case way,

var =3D ...something...
case
when num=3D=3D1 and ( var < 0 || var > 10 )
puts "var not valid for num=3D=3D1 !!!!!"
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!

Thanks.


=2D-=20
I=C3=B1aki Baz Castillo
 
R

Robert Dober

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

--=20
http://ruby-smalltalk.blogspot.com/
 
R

Robert Dober

El Viernes, 18 de Abril de 2008, Pe=F1a, Botp escribi=F3:



opss, I didn't know that a "when" can contain a comparision, nice to kno=
w!
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 =3D=3D=3D e then
a1
elsif e2 =3D=3D=3D e then
a2
else
a3
end

unfortunately
case e
when true
a

will only work for e =3D=3D true as
true =3D=3D=3D Object.new --> false

maybe Matz did not want to allow logical comparision in case ;)

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 =3D=3D=3D any; true end
end

case 42
when true
p true
else
p :else
end
HTH
R.
--=20
http://ruby-smalltalk.blogspot.com/
 
I

Iñaki Baz Castillo

El Viernes, 18 de Abril de 2008, Robert Dober escribi=F3:
try the following code with the line commented and then uncommented and
you will see what is going on

class TrueClass
# def =3D=3D=3D any; true end
end

case 42
when true
p true
else
p :else
end

Interesting, nice to know :)


=2D-=20
I=F1aki Baz Castillo
 
C

Christopher Dicely

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
 
R

Robert Dober

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
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_stuf= f
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/ =3D=3D=3D expression
...
when get_an_object( expression )
...
end

Sorry again, I outsmarted myself ;)

Cheers
Robert


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

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top