Tag Archives: lambdas

So I've been playing around with lambdas a bit lately - brushing up on closures is always fun. Ruby has.. several ways of implementing closures: you've got blocks, procs, lambdas, and methods. They're all of a similar flavor, but have subtle differences.

I found a great article by Erik Trautman and inspired me to play a bit with lambdas, so I wrote a simple test method in Rails console:

def my_func(n)
  puts n
  lambda do |w|
     puts w
     return w
   end
end

 

One of the cool things about lambdas is the return only returns from the lambda, not the outer method. So this means you can do something like this:

my_func('whoa!')
whoa!
 => #<Proc:0x007fdf6c231178@(irb):34 (lambda)>

And as you can see, the method puts the string passed to it, but what's returned is a Proc object - our lambda. It's basically sitting there, waiting for someone to call it and pass it an argument. This is pretty cool, and extremely powerful.

So let's try that - it looks something like this:

my_func('holy').call('smokes')
holy
smokes
 => "smokes" 

Now if we assign this to a variable, we can pull the same thing, pass some data to the variable and have it call our lambda, though this method isn't very useful. Notice that after the call() executes however, it returns a string, not the Proc object.

So let's consider a different example - also not extremely practical, but begins to show the flexibility and power lambdas give you.

Let's say we have a Rabbitt class, and we've created a couple of rabbitts (because..why not?). So if we think about querying for rabbitts, we can do something like this

def get_rabbits
  @rabbitts = Rabbitt.try(:all) rescue nil
end

So now, get_rabbits is going to give us back however many active record objects there are in the Rabbitt.all collection:

get_rabbits
  Rabbitt Load (0.2ms)  SELECT "rabbitts".* FROM "rabbitts"
 => #<ActiveRecord::Relation [#<Rabbitt id: 1, name: "Brier Sr.", color: "dark gray", language: "High Bunny", speed: 74, created_at: "2016-02-23 02:00:29", updated_at: "2016-02-23 02:01:03">, #<Rabbitt id: 2, name: "Teddy", color: "blue", language: "English", speed: 674, created_at: "2016-02-26 01:58:23", updated_at: "2016-02-26 01:58:23">]>

 

If we modify this method with a closure though, we can extract a rabbitt by name maybe...

def get_rabbits
  @rabbitts = Rabbitt.all rescue nil
  lambda do |name|
    @rabbitts.each{|r| return r if r.name.downcase == name.downcase}
    puts name #never fires if return completes above
  end
end

 

And let's try that call again, see if we can find Teddy

get_rabbits.call('teddy')
  Rabbitt Load (0.3ms)  SELECT "rabbitts".* FROM "rabbitts"
 => #<Rabbitt id: 2, name: "Teddy", color: "blue", language: "English", speed: 674, created_at: "2016-02-26 01:58:23", updated_at: "2016-02-26 01:58:23"> 
2.3.0 :024 > get_rabbits.call('teddy').speed
  Rabbitt Load (0.4ms)  SELECT "rabbitts".* FROM "rabbitts"
 => 674

Very cool, so we can fetch the collection, and get a single rabbitt record out of the same method. And notice what we've returned is a Rabbitt object:

get_rabbits.call('teddy').class
  Rabbitt Load (0.2ms)  SELECT "rabbitts".* FROM "rabbitts"
 => Rabbitt(id: integer, name: string, color: string, language: string, speed: integer, created_at: datetime, updated_at: datetime)