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 23.02.2007 02:55
on 23.02.2007 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 23.02.2007 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 23.02.2007 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 23.02.2007 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 23.02.2007 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 23.02.2007 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 23.02.2007 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 23.02.2007 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 23.02.2007 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 23.02.2007 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 23.02.2007 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 26.02.2007 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 28.02.2007 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 28.02.2007 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 28.02.2007 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 28.02.2007 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 28.02.2007 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.