|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
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. |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On Thu, May 22, 2008 at 6:20 PM, APNelson.L <APNelson.L@gmail.com> wrote:
> 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. 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. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
On May 22, 9:18pm, "APNelson.L" <APNelso...@gmail.com> wrote:
> 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. 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 Ruby 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. |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
Christopher Dicely 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. ![]() def method_caller(method, *args) method.call(*args) end a_method = method(:puts) method_caller(a_method, "foo") |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
I've been having conceptual problems with blocks and lambdas too. "I
never used them in <my_first_language> so clearly they're unnecessary!" ;-) 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! -- Posted via http://www.ruby-forum.com/. |
|
![]() |
| Outils de la discussion | |
|
|