Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ruby ALL the Closures

Ruby ALL the Closures

I was asked to give an introductory talk about blocks, Procs and Lambdas in the local Ruby Meetup in Montevideo. This is the result.

Pablo Astigarraga

May 14, 2013
Tweet

More Decks by Pablo Astigarraga

Other Decks in Programming

Transcript

  1. Wikipedia A closure is a function or reference to a

    function together with a referencing environment - a table storing a reference to each of the non-local variables (also called free variables) of that function. A closure - unlike a plain function pointer - allows a function to access those non-local variables even when invoked outside of its immediate lexical scope. Tuesday, May 14, 13
  2. Closures def counter(): x = 0 def increment(y): nonlocal x

    x += y print(x) return increment Tuesday, May 14, 13
  3. Closures counter1_increment = counter() counter2_increment = counter() counter1_increment(1) # prints

    1 counter1_increment(7) # prints 8 counter2_increment(1) # prints 1 counter1_increment(1) # prints 9 Tuesday, May 14, 13
  4. Closures def pretty_method pretty_variable = 0 this_is_a_lambda = ->(argument) {

    pretty_variable += argument puts pretty_variable } this_is_a_lambda end Tuesday, May 14, 13
  5. Closures method_1 = pretty_method method_2 = pretty_method method_1.call(1) # =>

    1 method_1.call(7) # => 8 method_2.call(1) # => 1 method_1.call(1) # => 9 Tuesday, May 14, 13
  6. blocks 999.times do |index| puts "#{ index } elefantes se

    balanceaban sobre la tela de una araña, como veian que resistía fueron a buscar otro elefante" end Tuesday, May 14, 13
  7. Blocks ['python', 'ruby', 'lua'].each do |language| puts "#{ language }

    is a pretty cool language!" end #=> python is a pretty cool language! # ruby is a pretty cool language! # lua is a pretty cool language! Tuesday, May 14, 13
  8. Blocks 5.times do |index| puts 'Lalala' end 5.times { |index|

    puts 'Lalala' } 5.times { |index| puts 'Lalala' } Tuesday, May 14, 13
  9. Procs p = Proc.new do |text| text.split(' ').each do |word|

    puts "#{ word } \n" } end puts "- ♪ 㽈" end p.call("uno dos tres cuatro cinco cinco seis") Tuesday, May 14, 13
  10. Procs p = Proc.new do |text| text.split(' ').each do |word|

    puts "#{ word } \n" } end puts "- ♪ 㽈" end p.call("uno dos tres cuatro cinco cinco seis") Tuesday, May 14, 13
  11. p = Proc.new do | text| text.split(' ').each do |word|

    puts "#{ word } \n" } end Tuesday, May 14, 13
  12. Who has done this? (function () { $.ajax({ url: "json.txt",

    dataType: 'json', cache: false, success: function (data, textStatus, jqXHR) { if (data.mySuccessProperty == "succeeded") { doX(); (function () { eval(data.dynamicFunction)(); })(); } else { doY(); (function () { alert("Z"); })(); } }, error: function (jqXHR, textStatus, error) { // handle error alert("error" + error); } }); })(); Tuesday, May 14, 13
  13. Who has done this? (function () { $.ajax({ url: "json.txt",

    dataType: 'json', cache: false, success: function (data, textStatus, jqXHR) { if (data.mySuccessProperty == "succeeded") { doX(); (function () { eval(data.dynamicFunction)(); })(); } else { doY(); (function () { alert("Z"); })(); } }, error: function (jqXHR, textStatus, error) { // handle error alert("error" + error); } }); })(); Tuesday, May 14, 13
  14. Procs callbacks = { success: Proc.new { |result| Services::EverythingWentWell.call(result: result)

    Services::NotifyEveryone.call }, error: Proc.new { |result| # Clean up mess # Log problem # Dance Polka } } def method_that_does_things(callbacks) if do_things callbacks[:success].call(result_of_things) else callbacks[:error].call(result_of_things) end end Tuesday, May 14, 13
  15. Lambdas class Array def iterate!(code) self.each_with_index do |n, i| self[i]

    = code.call(n) end end end array = [1, 2, 3, 4] array.iterate!(lambda { |n| n ** 2 }) puts array.inspect # => [1, 4, 9, 16] Tuesday, May 14, 13
  16. Lambdas def args(code) one, two = 1, 2 code.call(one, two)

    end args(Proc.new{|a, b, c| puts "Give me a #{a} and a #{b} and a #{c.class}"}) args(lambda{|a, b, c| puts "Give me a #{a} and a #{b} and a #{c.class}"}) # => Give me a 1 and a 2 and a NilClass # *.rb:8: ArgumentError: wrong number of arguments (2 for 3) (ArgumentError) Tuesday, May 14, 13
  17. Lambdas def proc_return Proc.new { return "Proc.new"}.call return "proc_return method

    finished" end def lambda_return lambda { return "lambda" }.call return "lambda_return method finished" end puts proc_return puts lambda_return # => Proc.new # => lambda_return method finished Tuesday, May 14, 13
  18. Links @poteland * Understanding Ruby Blocks, Procs and Lambdas -

    http://bit.ly/9qcstJ * This Talk - http://bit.ly/18IFJmP * More info - http://bit.ly/r8BnTA Tuesday, May 14, 13