i'm trying to be able to define a proc that can be called in the context of
self, eg:
block = lambda{ p 42 }
an_obj.instance_eval &block
but which can also be called with arguments, for example (imaginary ruby):
b = lambda{|x| p [x, y]}
class C
def y; 42; end
end
c = C::new
x = 42
c.arg_instance_eval(x, &b) #=> [42, 42]
any ideas?
-a
···
--
email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
Your life dwells amoung the causes of death
Like a lamp standing in a strong breeze. --Nagarjuna
i'm trying to be able to define a proc that can be called in the
context of self, eg:
block = lambda{ p 42 }
an_obj.instance_eval &block
but which can also be called with arguments, for example (imaginary
ruby):
b = lambda{|x| p [x, y]}
class C
def y; 42; end
end
c = C::new
x = 42
c.arg_instance_eval(x, &b) #=> [42, 42]
any ideas?
The only workaround that comes to mind is to pass self explicitely along
with other arguments. Or use a trick with delegation that allows to do
instance_eval on a proxy self that will also provide arguments given.
i'm trying to be able to define a proc that can be called in the context of
self, eg:
block = lambda{ p 42 }
an_obj.instance_eval &block
but which can also be called with arguments, for example (imaginary ruby):
b = lambda{|x| p [x, y]}
class C
def y; 42; end
end
c = C::new
x = 42
c.arg_instance_eval(x, &b) #=> [42, 42]
any ideas?
Tom (aka Trans) recently mentioned that he changed procs into methods in order to get what you want. Here's a quick hack, not efficient and not thread-safe, but maybe a start:
class Object
def arg_instance_eval( *args, &block )
c = class << self; self; end
c.send( :define_method, :arg_instance_eval_method, &block )
arg_instance_eval_method( *args )
ensure
c.send( :remove_method, :arg_instance_eval_method )
end
end
class Object
def evaluate(*args, &block)
...
end
end
??
another option would be to turn the problem inside out and do something like
l = lambda{ p x }
l.self = obj
l.call
this is what i have so far:
[ahoward@localhost ~]$ cat a.rb
class Object
def evaluate(*a, &b)
m = "____eval____#{ rand(65536) }____"
klass = Class === self ? self : self::class
klass.module_eval{ define_method m, &b }
begin
send m, *a
ensure
klass.module_eval{ remove_method m }
end
end
end
class C
def y
42
end
end
b = lambda{|x| p [x, y, self]}
c = C::new
x = 42
c.evaluate(x, &b) #=> [42, 42, #<C:0xb7f2f5c0>]
In message "Re: help with tricky proc/binding issue" > on Mon, 19 Sep 2005 23:42:12 +0900, "Ara.T.Howard" <Ara.T.Howard@noaa.gov> writes:
>i'm trying to be able to define a proc that can be called in the context of
>self, eg:
>
> block = lambda{ p 42 }
> an_obj.instance_eval &block
>
>but which can also be called with arguments, for example (imaginary ruby):
I understand what you want. But I haven't come up with a good name
for the function yet.
--
email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
Your life dwells amoung the causes of death
Like a lamp standing in a strong breeze. --Nagarjuna
>i'm trying to be able to define a proc that can be called in the context of
>self, eg:
>
> block = lambda{ p 42 }
> an_obj.instance_eval &block
>
>but which can also be called with arguments, for example (imaginary ruby):
I understand what you want. But I haven't come up with a good name
for the function yet.
What about Proc#with_self() that will return a new proc similar to the current one, but with a changed self context?
i'm trying to be able to define a proc that can be called in the
context of self, eg:
block = lambda{ p 42 }
an_obj.instance_eval &block
but which can also be called with arguments, for example (imaginary
ruby):
b = lambda{|x| p [x, y]}
class C
def y; 42; end
end
c = C::new
x = 42
c.arg_instance_eval(x, &b) #=> [42, 42]
any ideas?
Tom (aka Trans) recently mentioned that he changed procs into methods
in order to get what you want. Here's a quick hack, not efficient and
not thread-safe, but maybe a start:
class Object
def arg_instance_eval( *args, &block )
c = class << self; self; end
c.send( :define_method, :arg_instance_eval_method, &block )
arg_instance_eval_method( *args )
ensure
c.send( :remove_method, :arg_instance_eval_method )
end
end
Hacky but nice! For thread safety how about:
class Object
def arg_instance_eval( *args, &block )
c = class << self; self; end
meth = "__m_#{Thread.current.object_id}_#{rand 666}"
c.send( :define_method, meth, &block )
send( meth, *args )
ensure
c.send( :remove_method, meth )
end
end
class Object
def evaluate(*a, &b)
ret, sent = nil
loop do
m = "____evaluate____#{ rand(42) }____#{ rand(42) }____"
klass = Class === self ? self : self::class
begin
klass.module_eval{ define_method m, &b }
ret = send(sent = m, *a)
ensure
begin
klass.module_eval{ remove_method m }
ensure
break if sent
end
end
end
ret
end
end
class C
def y
42
end
end
b = lambda{|x| p [x, y, self]}
c = C::new
x = 42
c.evaluate(x, &b) #=> [42, 42, #<C:0xb7f2f5c0>]
guess that's the way to go for now.
cheers.
-a
···
On Tue, 20 Sep 2005, Pit Capitain wrote:
any ideas?
Tom (aka Trans) recently mentioned that he changed procs into methods in
order to get what you want. Here's a quick hack, not efficient and not
thread-safe, but maybe a start:
class Object
def arg_instance_eval( *args, &block )
c = class << self; self; end
c.send( :define_method, :arg_instance_eval_method, &block )
arg_instance_eval_method( *args )
ensure
c.send( :remove_method, :arg_instance_eval_method )
end
end
b = lambda{|x| p [x, y]}
class C
def y; 42; end
end
c = C::new
z = 41
c.arg_instance_eval( z, &b ) # => [41, 42]
--
email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
Your life dwells amoung the causes of death
Like a lamp standing in a strong breeze. --Nagarjuna
another option would be to turn the problem inside out and do something like
l = lambda{ p x }
l.self = obj
l.call
Procs are currently immutable and I'd assume that the source code assumes that they can not be changed in several places. It's less risky to return a new object with a changed self context, IMHO.
I've talked about this before, but the ability to return a new
proc with local variables manipulated would also be nice:
- Make "local" variables really local to the proc. Initialize
these to the current values of the local variables in the
previous binding. Effectively, this gives the proc its own
local binding (at least for "local" variables). This could be
done in conjunction with redefining self for the proc to.
It would also be nice to be able to be able to do the same
thing for blocks easily so that you could easily localize your
"local" variables in your block. But, you could emulate that
as long as you had a way to localize proc local variables:
foo(&(lambda{...}.localize))
or if you could do it directly to a block you may have some
syntax like this:
foo {{...}} # double braces to represent localization
But, that has some conflicts with hash. Not sure of a good
syntax. The problem is we can't apply methods directly to
blocks - you have to convert to Proc, apply the method, and
convert back.
···
--- Florian Groß <florgro@gmail.com> wrote:
Yukihiro Matsumoto wrote:
> >i'm trying to be able to define a proc that can be called
in the context of
> >self, eg:
> >
> > block = lambda{ p 42 }
> > an_obj.instance_eval &block
> >
> >but which can also be called with arguments, for example
(imaginary ruby):
>
> I understand what you want. But I haven't come up with a
good name
> for the function yet.
What about Proc#with_self() that will return a new proc
similar to the
current one, but with a changed self context?
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
class Object
def arg_instance_eval( *args, &block )
c = class << self; self; end
meth = "__m_#{Thread.current.object_id}_#{rand 666}"
--
email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
Your life dwells amoung the causes of death
Like a lamp standing in a strong breeze. --Nagarjuna
class Object
def evaluate(*a, &b)
ret, sent = nil
loop do
m = "____evaluate____#{ Thread::current.object_id }____#{ rand 666 }____#{ rand 42 }____"
klass = Class === self ? self : self::class
begin
klass.module_eval{ define_method m, &b }
ret = send(sent = m, *a)
ensure
begin
klass.module_eval{ remove_method m }
ensure
break if sent
end
end
end
ret
end
end
class C
def y
42
end
end
b = lambda{|x| p [x, y, self]}
c = C::new
x = 42
c.evaluate(x, &b) #=> [42, 42, #<C:0xb7f2f5c0>]
-a
···
On Tue, 20 Sep 2005, Robert Klemme wrote:
Hacky but nice! For thread safety how about:
--
email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
Your life dwells amoung the causes of death
Like a lamp standing in a strong breeze. --Nagarjuna
Procs are currently immutable and I'd assume that the source code
assumes that they can not be changed in several places. It's less risky
to return a new object with a changed self context, IMHO.