From: Ross Bamford Date: 2006-05-02T23:54:54+09:00 Subject: Re: Calling a block with some context. On Tue, 2006-05-02 at 17:17 +0900, benjohn@fysh.org wrote: > 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: >> lex_scope >> Hello from the calling context >> result >> changed -- Ross Bamford - rosco@roscopeco.REMOVE.co.uk