The problem with ruby is that you can't use a switch as it behaves with
many
other languages like C, php, etc.
For example, you want to convert the following peace of code to ruby:
switch (x) {
case 1:
case 2:
# do something
break;
case 3:
# do some other thing
break;
default:
}
it seems you can do it with the following code:
case x
when 1..2
# do something
when 3
# do some other thing
else
end
But when it comes to strings, you would like to be able to do simply:
case x
when "this"
when "that"
# do something common to "this" and "that"
when "nothing"
# something different
end
The problem is that you can't, because of the fact the "break" is
implicit
in
the ruby language.
The fact is that you don't want to rewrite the same code two times.
Of course, you would be able to right your code into a function, and
then
just
write:
case x
when "this"
func_this_that()
when "that"
func_this_that()
when "nothing"
# something different
end
But if again, you don't want to relay on a function call, here's a
solution
I thought about.
This is not perfect, because you have to change your syntax, but it
might be
quite useful in some cases.
# Redefine the === method of the Array class, that is used to match the
argument
# of the "case" directive.
class Array
# Return true if self contains any element of the given parameter.
def ===(o)
o.each do |e|
return true if self.include?(e)
end
false
end
end
# Example 1
x = ["case4"]
case x
when ["case1", "case2"]
puts "first case"
when ["case3", "case4", "case5"]
puts "second case"
when ["case6"]
puts "third case"
else
puts "not matched"
end
# Returns: "second case"
# Example 2
x = [6]
case x
when [1, 2]
puts "first case"
when [3, 4, 5]
puts "second case"
when [6]
puts "third case"
else
puts "not matched"
end
# Returns: "third case"
What do you think about it ?
on 2007-02-23 02:55
on 2007-02-23 03:14
Hi, On Fri, Feb 23, 2007 at 10:55:06AM +0900, Guillaume Nargeot wrote: > when "nothing" > # something different > end case x when "this", "that" func_this_that() when "nothing" # something different end
on 2007-02-23 03:24
Check this out for making your case statements work: http://redhanded.hobix.com/bits/wonderOfTheWhenBeFlat.html "Consider Olympic ice dancing out-graced!" -kjell
on 2007-02-23 04:23
On Fri, Feb 23, 2007 at 10:55:06AM +0900, Guillaume Nargeot wrote: > > But when it comes to strings, you would like to be able to do simply: > > case x > when "this" > when "that" > # do something common to "this" and "that" > when "nothing" > # something different > end These two examples are not equivalent. In one, you're listing multiple cases on a single line with the associated code following it. In the other, you're listing cases separately and letting the lack of a break cause it to fail over to the next -- which leads to a very unintuitive set of code. Why not just employ your list of cases for the same resulting code on one line? That works just fine.
on 2007-02-23 04:57
This is a long shot, but since there are many EE guys here... does anybody know if there's any effort going on for openaccess database ruby binding? I want to try it myself, but it looks like a big task, so I thought I ask first -andre
on 2007-02-23 05:23
Hi -- On Fri, 23 Feb 2007, Guillaume Nargeot wrote: > The problem with ruby is that you can't use a switch as it behaves with many > other languages like C, php, etc. I don't consider that a problem. If all languages had to behave exactly the same way, there would only be one language, and we'd all get bored :-) > return true if self.include?(e) > puts "first case" > # Example 2 > puts "not matched" > end > > # Returns: "third case" > > What do you think about it ? It's very dangerous. Remember that changing Array#=== changes it everywhere. There may be places in Ruby itself, or in other libraries you're using, that depend on the original behavior. David
on 2007-02-23 05:42
Guillaume Nargeot wrote: > else > puts "first case" > What do you think about it ? > You can already do this: a = [3, 4, 5] case x when 1, 2 puts "first case" when *a puts "second case" when 6 puts "third case" else puts "not matched" end There are cases of C's fall-through switch, that cannot be emulated by Ruby's case - and I think that's a good thing. To make breaks necessary to break out of a case clause (and creating the danger for programmers to incidentally forget one), was probably one of the most inane ideas of the C language's creators.
on 2007-02-23 06:05
> case x > when "this", "that" > func_this_that() > when "nothing" > # something different > end Thank you very much !!! I thought I tested everything, but obviously not this one. I didn't even find anything about it in the official documentation. So, thank you again, that is exactely what I needed ;)
on 2007-02-23 11:32
On Fri, Feb 23, 2007 at 02:05:10PM +0900, Guillaume Nargeot wrote: > > case x > > when "this", "that" > > func_this_that() > > when "nothing" > > # something different > > end > > Thank you very much !!! > I thought I tested everything, but obviously not this one. > I didn't even find anything about it in the official documentation. http://www.rubycentral.com/book/tut_expressions.html Search down to the section headed "Case Expressions"
on 2007-02-23 14:19
Le vendredi 23 février 2007 11:30, Brian Candler a écrit : > > I didn't even find anything about it in the official documentation. > > http://www.rubycentral.com/book/tut_expressions.html > Search down to the section headed "Case Expressions" I didn't know about this syntax, either. Thanks, Eban ! For the Strings, I thought about using Regex, instead : case x when /this|that/ func_this_that() when "nothing" # something different end
on 2007-02-23 16:27
On Fri, Feb 23, 2007 at 10:18:34PM +0900, Olivier Renaud wrote: > > > I thought I tested everything, but obviously not this one. > func_this_that() > when "nothing" > # something different > end That's not the same though. I think you'd need: when /\A(this|that)\z/ (which is a gotcha if you come from Perl, and expect to use ^...$ to match the start and end of the string) Regards, Brian.
on 2007-02-23 19:20
On 22 Feb., 22:54, Guillaume Nargeot <guillaume.nargeotDONOTFUCKINGS...@fusionsystems.co.jp> wrote: > case 3: > # do some other thing > break; > default: > > } For completeness sake, you can also emulate C's lack of a break; statement in ruby by doing redo/retry, like: a = 1 catch(:redo) do case a when 1 print '1' a = 2 redo when 2 puts 'and 2' end end This makes ruby's case statement probably the best of any language.
on 2007-02-26 08:43
> There are cases of C's fall-through switch, that cannot be emulated by > Ruby's case - and I think that's a good thing. To make breaks necessary > to break out of a case clause (and creating the danger for programmers > to incidentally forget one), was probably one of the most inane ideas of > the C language's creators. Yeah -- this is a feature which you might not recognize as such because you're used to the bug.
on 2007-02-28 20:36
gga schrieb: > redo > when 2 > puts 'and 2' > end > end > > This makes ruby's case statement probably the best of any language. I didn't know the "catch(:redo)". Is this documented somewhere? Regards, Pit
on 2007-02-28 20:55
On Thu, 1 Mar 2007 04:36:39 +0900, Pit Capitain <pit@capitain.de> wrote: >> catch(:redo) do >> case a >> when 1 >> print '1' >> a = 2 >> redo >> when 2 >> puts 'and 2' >> end >> end > I didn't know the "catch(:redo)". Is this documented somewhere? It doesn't have to be catch(:redo) specifically, and in fact its use may be misleading -- here, catch is simply being used to introduce an iteration context. For example, this works just as well: def foo ; yield ; end a = 1 foo do case a when 1 print '1' a = 2 redo when 2 puts 'and 2' end end -mental
on 2007-02-28 21:02
MenTaLguY schrieb: > It doesn't have to be catch(:redo) specifically, and in fact its use > may be misleading -- here, catch is simply being used to introduce an > iteration context. > (...) Ah, of course. Thanks Mental. Regards, Pit
on 2007-02-28 21:06
On 2/28/07, Pit Capitain <pit@capitain.de> wrote: > > a = 2 > > redo > > when 2 > > puts 'and 2' > > end > > end > > > > This makes ruby's case statement probably the best of any language. > > I didn't know the "catch(:redo)". Is this documented somewhere? Well the redo is really reacting as part of the catch block (though other block forms would do). Consider this example: def my_iter(exp) yield end my_iterr(p(:arg)) {p :block} #=> :arg and :ok once in order # Caution with the following. have ^C handy my_iter(p(:arg)) {p :before; redo; p :after} #=> :arg once and then infinite loop of :before my_iter(p(:arg)) {p :before; retry; p :after} #=> :arg then :before. both repeated infinitely Brian.
on 2007-02-28 21:15
On Thu, Mar 01, 2007 at 04:36:39AM +0900, Pit Capitain wrote: > > a = 2 > > redo > > when 2 > > puts 'and 2' > > end > >end > > > >This makes ruby's case statement probably the best of any language. > > I didn't know the "catch(:redo)". Is this documented somewhere? 'redo' is documented at http://www.rubycentral.com/book/tut_expressions.html 'catch' is documented at http://www.rubycentral.com/book/tut_exceptions.html However they're not a pair, and I don't think that 'catch' does anything in particular in the above example, apart from causing the block to be executed once. You could achieve the same with: a = 1 1.times do case a when 1 print '1' a = 2 redo when 2 puts 'and 2' end end Or: a = 1 begin case a when 1 print '1' a = 2 redo when 2 puts 'and 2' end end while false Regards, Brian.
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.