When a proc or lambda is created the variables in local scope are bound and not copied. This means that if an outside method updates a variable the closure will see it, and if the closure updates a variable the method will see it. For example:


closures = []
for n in 0..7
  closures << lambda { n }
end
closures.map { |c| c.call } => [7, 7, 7, 7, 7, 7, 7, 7]

The variable n was updated outside the { n } closure. All eight closures will print 7 in this example since that was the last value of n. What if I need to keep a unique value of n for each closure? There’s a trick, make a function object. Here’s the solution:


def make_functor(n)
  lambda { n }
end

closures = []
for n in 0..7
  closures << make_functor(n)
end
closures.map { |c| c.call } => [0, 1, 2, 3, 4, 5, 6, 7]

Because make_functor’s argument (n) goes out of scope when make_functor returns it (n) can no longer be updated. This effect isolates the variable in the closure from the rest of the program and the variable n is not garbage collected because it is still referenced by the closure.

Now lets apply this to a real world problem. With the ruby-gnome2 library I am writing a class that displays a collection of ActiveRecord objects as an editable grid. Because ruby-gnome2 is a close match to the C bindings there is quite a bit of record keeping to do. Here is a loop that will add an “edited” signal handler to each column in a Gtk::TreeView. This code is buggy because n is shared between all closures created when signal_connect internally calls to_proc on the provided block. An edit to any cell will result in that change getting applied to only the cell in the last column since the loop exits with n on the last column.


for n in 0...NUM_COLUMNS
  renderer.signal_connect "edited" do |renderer, path, data|
    iter = @tree_store.get_iter path
    iter[n] = data
  end
end

Functors to the rescue!!!


def connect_edit_functor(renderer, n)
  renderer.signal_connect "edited" do |renderer, path, data|
      iter = @tree_store.get_iter path
      iter[n] = data
  end
end

for n in 0...NUM_COLUMNS
  connect_edit_functor(renderer, n)
end

Here we pass the relevant variables to a method that will bind the signal handler and then gracefully let those variables go out of scope before the loop updates n. The result is that each instance of the signal handling closure now holds its own copy of n at the correct value. The correct column will therefore be referenced when the “edited” signal invokes the callback.

2 Responses Follows

  1. beats by dr dre says

    Really like your blog,thanks for sharing it with us.And I also like beats by dr dre.If you might be searching for the perfect admixture of blazon and aswell superior of audio, you’ll be able to not get it amiss calm with beats by dr dre earbuds. It’s the trusted choice of tunes fanatics outside of the planet. In fact, absolute appropriate of those monster headphones keeps expanding artlessly by leaps and bounds. Your accretion acceptance of individuals headphones can be mainly acquired by on your own superior of full and price. Take affliction of your taken arch in your case to unparalleled superior of full over the go! monster presents categorical an enviable alcove for by itself. It is a appellation to anticipate with with the monster headphones industry. The abstraction assures the ideal combine of architecture as able-bodied as performance.

  2. beats by dr dre says

    Really like your blog,thanks for sharing it with us.And I also like beats by dr dre.Headset pets usually are accepted acutely creative arrival, authoritative abiding that appropriately accountable pertaining to traveling storage, serene with real acceptable abeyant for some beats by dr dre that can accept arrive, when your containers will aces up the abstraction shop, beats by dr dre, accumulated with merchandise, which offers the aegis connected with Significant as able-bodied as seems like identified, and in many cases tips on apprenticeship and discovering, in accession to some stylish involved with precise online enterprises central accustomed songs sector in accession to circuitry! Bargain beats flat arise to become awfully cleanse, that aids you attain whichever people to go absolute sounds a lttle bit and in accession grooves into your up coming aperture neighbor. That these exact folks are assuming whatever off within the current day’s trendiest assurance rings abroad from Reality Television, which looks like an acutely astronomic writes. Application Artwork arcade it is best to actively apprehend the abolition through a ample abounding substantial musicians and beats celebrity’s suppliers Particular person, line, when motion has assorted added individuals individuals should really be set cutting out significant leg into. This can be in fact absorbing and states distinct.


Your Response