Calling a block with some context

I would like to be able to call a block / proc / lambda with the current
context (as well as the context it was created in):

def make_proc
  Proc.new {puts from_calling_context}
end

proc = make_proc
from_calling_context = 'Hello from the calling context'
call_with_my_context( proc )

... Something like that.

Thanks for any thoughts,
  Benjohn

I would like to be able to call a block / proc / lambda with the current
context (as well as the context it was created in):

def make_proc
  Proc.new {puts from_calling_context}
end

proc = make_proc
from_calling_context = 'Hello from the calling context'
call_with_my_context( proc )

This is something that's been discussed quite a bit I think, with the
general conclusion being that it's not possible to rebind procs like
this.

You can emulate it up to a point, but with some potentially serious
quirks, e.g:

require 'facet/binding'
require 'ostruct'

def call_with_my_context(blk)
  Binding.of_caller do |b|
    o = OpenStruct.new
    b.local_variables.each { |v| o.send("#{v}=", b[v]) }
    r = o.instance_eval(&blk)
    o.methods.select { |m| m =~ /[^=]=$/ }.each { |v| v = v[0..-2]; b[v] = o.send(v) }
    r
  end
end

def make_proc
  avar = :lex_scope
  Proc.new do |ret| # only need arg if you want to change vars outside the proc
    puts avar
    puts from_calling_context;
    ret.from_calling_context = 'changed' # such as here
    "result"
  end
end

blk = make_proc
from_calling_context = 'Hello from the calling context'
puts call_with_my_context(blk)
puts from_calling_context

Outputs:

···

On Tue, 2006-05-02 at 17:17 +0900, benjohn@fysh.org wrote:

lex_scope
Hello from the calling context
result
changed

--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk