Newbie: two cool discoveries

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.

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

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

Hope that helped someone :slight_smile:

Diego

the “&” is a shortcut to “to_proc”

class Symbol
def to_proc
lambda { |x| x.send(self) }
end
end

So in theory, you could use to send any message

( Ruby 1.9* btw )

On Fri, Nov 26, 2010 at 3:00 PM, Diego V.
[email protected] wrote:

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.

Cheers

robert

On Nov 26, 7:56am, Diego V. [email protected] wrote:

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}

when proc{|x| x.respond_to?(:to_a) && x.size>1}

Using a Proc in this way doesn’t work under Ruby 1.8.7.

On Nov 26, 8:11am, Arturo G. [email protected] wrote:

the “&” is a shortcut to “to_proc”

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

end
end

So in theory, you could use to send any message

( Ruby 1.9* btw )

Why in the world do you say that?

[-9].map(&:abs)
==>[9]
VERSION
==>“1.8.7”

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. :slight_smile: 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!!! :slight_smile:

Diego

On Saturday 27 November 2010 00:45:14 w_a_x_man wrote:

On Nov 26, 8:11 am, Arturo G. [email protected] wrote:

the “&” is a shortcut to “to_proc”

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.

On Fri, Nov 26, 2010 at 6:45 PM, w_a_x_man [email protected] wrote:

Because lambda is more pretentious (at least, thats why I use it)

They actually have different meanings, though (sometimes)

$ cat proc_vs_lambda.rb
def invoke_lambda
lambda { return 1 }.call
return 2
end

def invoke_proc
proc { return 1 }.call
return 2
end

require ‘pp’
puts ENV[‘RUBY_VERSION’]
puts invoke_lambda # => 2
puts invoke_proc # => 1
puts

$ rvm proc_vs_lambda.rb
jruby-1.5.3
2
2

macruby-0.7
2
1

rbx-1.1.0-20100923
2
2

ruby-1.8.6-p399
2
2

ruby-1.8.7-p302
2
2

ruby-1.9.1-p378
2
1

ruby-1.9.2-p0
2
1