Forum: Ruby Calling a block with some context.

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
unknown (Guest)
on 2006-05-03 20:59
(Received via mailing list)
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
Ross B. (Guest)
on 2006-05-03 20:59
(Received via mailing list)
On Tue, 2006-05-02 at 17:17 +0900, removed_email_address@domain.invalid 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:
This topic is locked and can not be replied to.