The following piece of code works only if I use "x.green" rather than just
plain "green"
class Foo
def red(&p) @z = p
end
def blue(y)
instance_eval{@z.call y}
end
def green
puts "Yeah!"
end
end
x = Foo.new
x.red do |y|
green # I don't want to use x.green
puts y
end
x.blue 5
The following code works. It is able to call the "green" method from inside
the Foo class without being able to prefix it with "x.", but I can't handle
any arguments like in the above code:
class Foo
def red(&p) @z = p
end
def blue
instance_eval(&@z)
end
def green
puts "Yeah!"
end
end
x = Foo.new
x.red do
green
end
x.blue
My main goal is to be able to refer to the "green" in the closure "x.red do
green end" without using "x.green" and also be able handle arguments at the
same time like in the first piece of code, but as you know, the first piece
of code doesn't work.
I don't think so. I think there was a thread about adding an
argument passing instance_eval type method and matz was asking
for suggestions of method names.
What's so bad about using a receiver for Foo#green? Using
instance_eval can be dangerous because you bypass all
protections/encapsulation. It also can get confusing because
the block only has access to local variables in the defining
context and not methods, instance variables, etc like other
blocks have access to.
Personally, I think it is better to pass in self as an argument
rather than use instance_eval so casually. I usually use
instance_eval only when I have to - to bypass proctections.
···
--- Martin <yodlep@gmail.com> wrote:
Hi,
I'm having trouble with Procs.
The following piece of code works only if I use "x.green"
rather than just
plain "green"
class Foo
def red(&p) @z = p
end
def blue(y)
instance_eval{@z.call y}
end
def green
puts "Yeah!"
end
end
x = Foo.new
x.red do |y|
green # I don't want to use x.green
puts y
end
x.blue 5
The following code works. It is able to call the "green"
method from inside
the Foo class without being able to prefix it with "x.", but
I can't handle
any arguments like in the above code:
class Foo
def red(&p) @z = p
end
def blue
instance_eval(&@z)
end
def green
puts "Yeah!"
end
end
x = Foo.new
x.red do
green
end
x.blue
My main goal is to be able to refer to the "green" in the
closure "x.red do
green end" without using "x.green" and also be able handle
arguments at the
same time like in the first piece of code, but as you know,
the first piece
of code doesn't work.
Is there any way to achieve this?
__________________________________
Yahoo! Mail - PC Magazine Editors' Choice 2005
I was able to mold it to the way I wanted it. Now it can temporarily define
a method, call the method with arguments and then undefine the temporary
method. I'm guessing this comes with a cost? slowness?
class Foo
def red(&p) @z = p
end
def blue(y)
Foo.send(:define_method, :blue_temp, @z)
blue_temp(y)
Foo.send(:undef_method, :blue_temp)
end
Scratch that - it defines a method on the class not the object so all
Foos would get the z method. Hmm.. I'll have to think about this
(should have done that before I posted
Sean
···
On 10/12/05, Sean O'Halpin <sean.ohalpin@gmail.com> wrote:
This isn't quite what you asked for but it achieves the same effect:
class Foo
def red(&p)
self.class.send(:define_method, :z, &p)
end
fyi. i posted this code a while back, it does the above in a thread-safe way:
harp:~ > cat a.rb
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 Foo
attr_accessor "rb"
def red &b
self.rb = b
end
def blue y
evaluate y, &rb
end
def green
puts "green"
end
end
foo = Foo::new
foo.red do |y|
green
puts y
end
foo.blue 5
harp:~ > ruby a.rb
green
5
and yes, it's probaly slow.
cheers.
-a
···
On Wed, 12 Oct 2005, Martin wrote:
Now that is a super cool ruby hack. Thank you.
I was able to mold it to the way I wanted it. Now it can temporarily define
a method, call the method with arguments and then undefine the temporary
method. I'm guessing this comes with a cost? slowness?
class Foo
def red(&p) @z = p
end
def blue(y)
Foo.send(:define_method, :blue_temp, @z)
blue_temp(y)
Foo.send(:undef_method, :blue_temp)
end
def green
puts "Yeah!"
end
end
x = Foo.new
x.red do |y|
green
puts y
end
x.blue 5
--
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
What do you think of the singleton method version? That doesn't need
to be thread safe in the same way (no more than any concurrent access
to the same object)