Lambda Block vs. Method

I was just wondering what the benefit would be of creating a block
that can be called rather than defining a method. Here is an example:

def puts_time(x)
puts x
end

instead of…

puts_time = lambda { |x| puts x }

personally I see no reason to create a block like this instead of a
method.

On Thu, May 22, 2008 at 6:20 PM, APNelson.L [email protected]
wrote:

personally I see no reason to create a block like this instead of a
method.

You can pass a lambda or proc to another method, which you can’t
exactly do with a method (you can get most of the same effect by
passing the method on which the method is defined and the method name,
and calling the method that way.) But, yes, more generally OOP and
functional programming are essentially different techniques which
often can be used to save the same ends, so often having access to
both techniques may seem redundant.

On May 22, 9:18 pm, “APNelson.L” [email protected] wrote:

personally I see no reason to create a block like this instead of a
method.

Well lambda returns a Proc instance, and you can store a Proc in a
variable for later use, pass one or more Procs into a method as
parameters, and a method can return a Proc. This allows code to be
treated as data and this gives you a higher level of abstraction or a
greater degree of flexibility.

Here’s an example. Suppose you have tons of data and would like to
allow the user to filter it in various ways. Perhaps you’ll even
provide the set of available filters in a drop-down menu or such. Now
you could write some code where in some case statement you determine
which filter was selected and then call a method of a pre-determined
name that implements that filter.

Or you could do something along these lines:

require ‘date’

date_count = 25

create an array of some random dates in the last ~two

years

somewhat biased to be more

recent
some_dates =
(1…date_count).map { Date.today - rand(rand(2 * 365)) }

set up some useful date

filters
date_filters = {
“previous year” =>
lambda { |d| d.year == Date.today.year - 1 },
“this year” =>
lambda { |d| d.year == Date.today.year },
“last 12 months” =>
lambda { |d| (0…364) === Date.today - d ||
# add special leap year
check
(Date.today - d == 365 && Date.today.mday != d.mday) },
“last 7 days” =>
lambda { |d| (0…6) === Date.today - d }
}

try each filter out against the random

dates
date_filters.each do |label, filter|
puts “The following dates are all in the #{label}:”
puts some_dates.select { |d| filter.call(d) }.join("\n")
end

So now you have the filters stored as data in a data structure, and
you can use this relatively easily from multiple places throughout
your program.

What do you think? Can you imagine this being useful?

Eric

====

LearnRuby.com offers Rails & Ruby HANDS-ON public & ON-SITE
workshops.
Ruby Fundamentals Wkshp June 16-18 Ann Arbor, Mich.
Ready for Rails R. Wkshp June 23-24 Ann Arbor, Mich.
Ruby on Rails Wkshp June 25-27 Ann Arbor, Mich.
Ruby Plus Rails Combo Wkshp June 23-27 Ann Arbor, Mich
Please visit http://LearnRuby.com for all the details.

You can pass a lambda or proc to another method, which you can’t
exactly do with a method (you can get most of the same effect by
passing the method on which the method is defined and the method name,
and calling the method that way.)

Actually, you can pass a method to another method using the method
method. :wink:

def method_caller(method, *args)
method.call(*args)
end

a_method = method(:puts)
method_caller(a_method, “foo”)

All these gyrations. Wouldn’t it just be simpler to give Ruby
first-class functions?

I’ve been having conceptual problems with blocks and lambdas too. “I
never used them in <my_first_language> so clearly they’re unnecessary!”
:wink: I think it’s a question of forcing oneself to think in a new and
different way, which is always a difficult process.

Programming languages are mostly designed by people with a computer
science background, so notions like lambda calculus, Lisp and functional
programming are part of their toolkit. (Don’t know what Matz’s
background is.) Ordinary folks who come to programming via engineering
or science or other disciplines, or who started with Basic, don’t have
the same ways of thinking, so it can take some mental contortions to
understand Ruby’s constructs.

The problem for me is that I haven’t seen any convincing examples where
a Ruby block couldn’t be replaced by another way of doing the same job.
(Actually we’re forced to use blocks instead of “for” loops, but so far
I’ve been able to handle that by learning the syntax without really
understanding what’s going on underneath.)

Hopefully one day soon I’ll see the light!

Christopher D. wrote:

You can pass a lambda or proc to another method, which you can’t
exactly do with a method (you can get most of the same effect by
passing the method on which the method is defined and the method name,
and calling the method that way.)

Actually, you can pass a method to another method using the method
method. :wink:

def method_caller(method, *args)
method.call(*args)
end

a_method = method(:puts)
method_caller(a_method, “foo”)

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs