Hi all,
I just wanted to share a couple of things I’ve found out lately. I
imagine they are well known to the experts here, but I thought maybe
there are other newbies out there that could benefit from it too.
Using proc in the case statement:
I find the case statement particularly elegant: especially when
there’s a long list of choices I much prefer it to using if…
elsif… else… end. That said the latter offers a lot more
flexibility. Still a lot can be accomplished by using procs. For
example:
case val
when Hash
…
when lambda{|x| x.respond_to?(:to_ary) && x.length>1}
…
end
The block takes the case argument and its output (generally true or
false…) is used to decide if the branch should be run or not.
Passing a block to map or similar methods.
Say you have an array of numbers, and you want to invoke #abs for each
number. Rather than:
x = [1,-2,3,-4,5]
x.map{|x| x.abs}
you can use:
x = [1,-2,3,-4,5]
x.map(&:abs)
It may not seem much in this instance, but I found it a lot cleaner in
some cases, especially when there is a long chain of methods.
I find the case statement particularly elegant: especially when
there’s a long list of choices I much prefer it to using if…
elsif… else… end. That said the latter offers a lot more
flexibility.
I’m curios to hear whether you maintain that statement after seeing
the other (apparently mostly unknown) variant of case:
case # nothing here!
when x > 1
puts “great”
when sun.shines && temp > 20
puts “warm”
when 3 == 9, 21 < 17
puts “weird”
else
puts “what?”
end
This is basically the same as an if-elsif-else-end cascade with a
shorter syntax for “||” (i.e. the comma after “when”).
Also, you can return values from case statements:
puts case # nothing here!
when x > 1
“great”
when sun.shines && temp > 20
“warm”
when 3 == 9, 21 < 17
“weird”
else
“what?”
end
Of course this can also be done with if-elsif-else-end.
class Symbol
def to_proc
lambda { |x| x.send(self) }
Note that it’s to_proc, not to_lambda. I don’t see why
anyone would want to type the gibberish “lambda” when
he could type the shorter and clearer “proc”.
This is basically the same as an if-elsif-else-end cascade with a
shorter syntax for “||” (i.e. the comma after “when”).
Good point. It never came to my mind that you could forget to give
“case” an argument to turn it into an if-elsif-else-end. Very nice.
About the comma though I don’t find it very legible: it’s fine for
normal use (like 1,3 or Array,Hash), but not as a generic or.
(obviously this is a very personal opinion). But I imagine that
there’s nothing stopping you from using || when you feel it reads
better.
Anyway, I must admit that this makes case at least as useable than if-
elsif-else-end while possibly being more readable in a lot of cases.
I’d still prefer to use the latter when it’s more readable, and I can
of prefer it if there are not many branches, but this is purely
personal opinion. Long live CASE!!!
class Symbol
def to_proc
lambda { |x| x.send(self) }
Note that it’s to_proc, not to_lambda. I don’t see why
anyone would want to type the gibberish “lambda” when
he could type the shorter and clearer “proc”.
Yes, is to_proc. not because is shorter and clearer, btw, but because
is
to_proc.