Strange behaviour - Instantiating an object and giving it a

Hi,

In both examples below, the expected results are observed. However,
in the second example (class Bar) warnings are generated. This is
Ruby 1.8.2 on Mac Os x 10.4.7.

I wonder if someone might be able to enlighten me?

Chris

class Foo
def initialize(&proc)
meta = class << self; self; end
meta.send(:define_method, :bar, &proc)
end
end

foo = Foo.new { false }
puts foo.bar #=> false
foo = Foo.new { ‘hello world’ }
puts foo.bar #=> hello_world

class Bar
def initialize(&proc)
class << self
define_method(:foo, &proc)
end
end
end

bar = Bar.new { false }
#=> warning:â?? tried to create Proc object without a block
puts bar.foo #=> false
bar = Bar.new { ‘hello_world’ }
#=> warning:â?? tried to create Proc object without a block
puts bar.foo #=> hello_world

Ok, so it seems to be with scoping and my choice of the proc variable
name.

Anything other than a variable named proc will cause the more
understandable

=> NameError: undefined local variable or method `prc’ for
#<Class:#Foo:0x342054>

Chris

The following seem a more straight-forward approach to what I think
you are trying to do. Have I missed something?

class Foo

def Foo.make_bar(&block)
   define_method(:bar, &block)
end

# Each instance will have its own version of method "bar".
def initialize(&block)
   Foo.make_bar(&block)
end

end

Foo.new {puts “foobar”}.bar => foobar
Foo.new {|s| printf “%s %s\n”, s, s}.bar(“foobar”) => foobar foobar
Foo.new {|m, n| p m + n}.bar(2, 3) => 5

Regards, Morton

Thanks for pointing this out. I did indeed miss an important point.
Regards, Morton

I now propose this as a more straight-forward solution to the problem.

class Foo

# Each instance will have its own version of method "bar".
def initialize(&block)
   @block = block
   def self.bar(*args)
      @block.call(*args)
   end
end

end

a = Foo.new {puts “foobar”}
b = Foo.new {|s| printf “%s %s\n”, s, s}
c = Foo.new {|m, n| p m + n}
a.bar => foobar
b.bar(“foobar”) => foobar foobar
c.bar(2, 3) => 5

Regards, Morton

“M” == Morton G. [email protected] writes:

M> # Each instance will have its own version of method “bar”.

no, not really

moulon% cat b.rb
#!/usr/bin/ruby
class Foo

def Foo.make_bar(&block)
define_method(:bar, &block)
end

Each instance will have its own version of method “bar”.

def initialize(&block)
Foo.make_bar(&block)
end

end

f = Foo.new {puts “foobar”}
f.bar
Foo.new {|s| printf “%s %s\n”, s, s}.bar(“foobar”)
f.bar(“xxxxx”)
moulon%

moulon% ./b.rb
foobar
foobar foobar
xxxxx xxxxx
moulon%

Guy Decoux

Thanks for the response guys. As it turns out I didn’t need it
anyway…

Chris