# Strange behaviour - Instantiating an object and giving it a

**URL:** <https://www.ruby-forum.com/t/strange-behaviour-instantiating-an-object-and-giving-it-a/98823>\
**Category:** Ruby\
**Created:** [July 18, 2006, 1:42pm UTC](https://www.ruby-forum.com/t/strange-behaviour-instantiating-an-object-and-giving-it-a/98823 "2006-07-18T13:42:11Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![crenner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/278dde/32.png) [@crenner](https://www.ruby-forum.com/u/crenner)\
**Post date:** [July 18, 2006, 1:42pm UTC](https://www.ruby-forum.com/t/strange-behaviour-instantiating-an-object-and-giving-it-a/98823/1 "2006-07-18T13:42:11Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![crenner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/278dde/32.png) [@crenner](https://www.ruby-forum.com/u/crenner)\
**Post date:** [July 18, 2006, 1:54pm UTC](https://www.ruby-forum.com/t/strange-behaviour-instantiating-an-object-and-giving-it-a/98823/2 "2006-07-18T13:54:34Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![crenner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/278dde/32.png) [@crenner](https://www.ruby-forum.com/u/crenner)\
**Post date:** [July 18, 2006, 3:12pm UTC](https://www.ruby-forum.com/t/strange-behaviour-instantiating-an-object-and-giving-it-a/98823/3 "2006-07-18T15:12:37Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![crenner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/278dde/32.png) [@crenner](https://www.ruby-forum.com/u/crenner)\
**Post date:** [July 18, 2006, 3:59pm UTC](https://www.ruby-forum.com/t/strange-behaviour-instantiating-an-object-and-giving-it-a/98823/4 "2006-07-18T15:59:36Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![crenner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/278dde/32.png) [@crenner](https://www.ruby-forum.com/u/crenner)\
**Post date:** [July 18, 2006, 4:15pm UTC](https://www.ruby-forum.com/t/strange-behaviour-instantiating-an-object-and-giving-it-a/98823/5 "2006-07-18T16:15:10Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![crenner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/278dde/32.png) [@crenner](https://www.ruby-forum.com/u/crenner)\
**Post date:** [July 18, 2006, 3:18pm UTC](https://www.ruby-forum.com/t/strange-behaviour-instantiating-an-object-and-giving-it-a/98823/6 "2006-07-18T15:18:52Z")

</div>

> > > > > “M” == Morton G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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

---

<div class="post-metadata">

**Author:** ![crenner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/278dde/32.png) [@crenner](https://www.ruby-forum.com/u/crenner)\
**Post date:** [July 20, 2006, 11:48am UTC](https://www.ruby-forum.com/t/strange-behaviour-instantiating-an-object-and-giving-it-a/98823/7 "2006-07-20T11:48:36Z")

</div>

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

Chris
