From: Nikodemus Siivola Date: 2002-10-17T06:54:27+09:00 Subject: Re: Precompiling eval expressions On Thu, 17 Oct 2002, Brian Candler wrote: > (Can anyone point me to a good explanation of what is going on underneath?) Procs are closures: they contain their enclosing environment (ie. as a pointer to a stack frame). This is cool because it enables you to create the kinds of functions you need, dynamically: def adder n proc { |x| x + n } # The n is part of the environment, see? end a = adder 1 # But is actually 1 here b = adder 2 # and 2 here a.call(1) # => 1 ...hence the different behaviour b.call(1) # => 3 This storage of context is also why they are expensive, and why you should pass blocks, instead of procs to methods when you have the choise: def one # Better, provided that the outside context is not needed yield end def two # Useless proc creation unless you are going to store it somewere Proc.new.call end one { puts "No context" } two { puts "context" } If you really want to grok them, I recommend the "Structure and Interpretation of Computer Programs", esp. the metacircular evaluator part. It's a bloody good book, and it's online. Hope this helps, -- Nikodemus