Hi
I'm trying to invoke a method defined in one class with self set to an
instance of a different class. I didn't have much success (as shown
below). Is there another way to achieve this?
Many thanks
Paul
···
----
class Foo
def foo
print
end
def print
puts "foo"
end
def test bar
foo_proc = Proc.new { print }
# Prints bar
bar.instance_eval(&foo_proc)
# 1.8.6 Fails with "wrong number of arguments (1 for 0) (ArgumentError)"
# 1.9.1 Prints foo
bar.instance_eval(&method(:foo))
end
end
class Bar
def print
puts "bar"
end
end
Foo.new.test Bar.new
Paul Carey wrote:
I'm trying to invoke a method defined in one class with self set to an
instance of a different class.
If the method is in a common superclass, then you can make an
UnboundMethod and bind it to the new object. e.g.
class Foo; def foo; puts inspect; end; end
=> nil
class Bar < Foo; end
=> nil
b = Bar.new
=> #<Bar:0xb7c04998>
Foo.instance_method(:foo).bind(b).call
#<Bar:0xb7c04998>
=> nil
But otherwise I don't think you can detach arbitrary methods from one
class and apply them to an object of an unrelated class. You'd probably
be best putting the relevant method(s) in a mixin, and then sharing that
between the classes, or adding those methods to the singleton class of
the individual object you're interested in.
module Baz; def baz; puts "baz!"; end; end
=> nil
s = "hello"
=> "hello"
s.extend Baz
=> "hello"
s.baz
baz!
=> nil
···
--
Posted via http://www.ruby-forum.com/\.
Brian Candler wrote:
If the method is in a common superclass, then you can make an
UnboundMethod and bind it to the new object. e.g.
class Foo; def foo; puts inspect; end; end
=> nil
class Bar < Foo; end
=> nil
b = Bar.new
=> #<Bar:0xb7c04998>
Foo.instance_method(:foo).bind(b).call
#<Bar:0xb7c04998>
=> nil
... and of course, object b usually has the 'foo' method already
inherited from the parent, in which case b.send(:foo) is sufficient.
But if 'foo' has been overridden, it can still be useful to bind this
way.
class Foo; def foo; puts "foo from parent"; end; end
=> nil
class Bar < Foo; def foo; puts "foo from child"; end; end
=> nil
b = Bar.new
=> #<Bar:0xb7cf1cfc>
b.send(:foo)
foo from child
=> nil
m = Foo.instance_method(:foo)
=> #<UnboundMethod: Foo#foo>
m.bind(b).call
foo from parent
=> nil
···
--
Posted via http://www.ruby-forum.com/\.
I'm trying to invoke a method defined in one class with self set to an
instance of a different class.
You'd probably be best ... or adding those methods to the singleton
class of the individual object you're interested in.
Thanks Brian, I went with adding the methods to the singleton class.
Paul