Skip to content

Instantly share code, notes, and snippets.

@gcentauri
Created April 28, 2021 19:54
Show Gist options
  • Save gcentauri/ffb6bf23b5858bca2eaca023a9c702f5 to your computer and use it in GitHub Desktop.
Save gcentauri/ffb6bf23b5858bca2eaca023a9c702f5 to your computer and use it in GitHub Desktop.
Blocks, Procks, and Lambdas

Blocks, Procs, and Lambdas

in some ways a closure is just like an object that contains state and responds to the single method #call. for example:

    # Makes counter objects that increment by 1 every time it is called
    class Counter
      def initialize
        @count = 0
      end
    
      def call
        @count += 1
      end
    end
    
    counter = Counter.new
    counter.call # => 1
    counter.call # => 2
    counter.call # => 3
    # returns a closure (Proc) we can call to count up
    def make_counter
      i = 0
    
      -> { i += 1 }
    end
    
    closure_counter = make_counter
    closure_counter.call # => 1
    closure_counter.call # => 2
    closure_counter.call # => 3

the key to how this works is the concept of "binding" and an "environment". Ruby, as expected, has a class Binding to implement this concept.

Objects of class Binding encapsulate the execution context at some particular place in the code and retain this context for future use. The variables, methods, value of self, and possibly an iterator block that can be accessed in this context are all retained.

These binding objects can be passed as the second argument of the Kernel#eval method, establishing an environment for the evaluation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment