Ruby Blocks, Procs and Local Variables

ruby

Solution

The `Proc.new` call creates a closure for the block that it's given. In creating a closure for the block, the block is bound to the original variables in the scope of the `Proc.new` call.

Why is this done?

It allows Ruby blocks to function as closures. Closures are extremely useful, and the Wikipedia entry (linked above) does an excellent job of explaining some of their applications.

How is this done?

This is done in the Ruby VM (in C code) by copying the Ruby control frame that exists before entering the `Proc.new` method. The block is then run in the context of this control frame. This effectively copies all of the bindings that are present in this frame. In Ruby 1.8, you can find the code for this in the `proc_alloc` function in `eval.c`. In Ruby 1.9, you can find this in the `proc_new` function in `proc.c`.

Problem

In Ruby, procs seem to have access to local variables that were present at the time they were declared, even if they are executed in a different scope: ``` module Scope1 def self.scope1_method puts "In scope1_method" end end module Scope2 def self.get_proc x = 42 Proc.new do puts x puts self scope1_method end end end Scope1.instance_eval(&Scope2.get_proc) ``` Output: ``` 42 Scope1 In scope1_method ``` How and why does this occur?

Original source