Instance_eval with method proc

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 C. 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

Brian C. 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

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