# Method\_added/define\_method infinite loop

**URL:** <https://www.ruby-forum.com/t/method-added-define-method-infinite-loop/120070>\
**Category:** Ruby\
**Created:** [November 13, 2007, 3:25pm UTC](https://www.ruby-forum.com/t/method-added-define-method-infinite-loop/120070 "2007-11-13T15:25:41Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [November 13, 2007, 3:25pm UTC](https://www.ruby-forum.com/t/method-added-define-method-infinite-loop/120070/1 "2007-11-13T15:25:41Z")

</div>

What’s the best way to avoid the classic method\_added/define\_method  
infinite loop?

class X  
def self.method\_added(name)  
p name  
define\_method(name)  
# do something else  
end  
end

```
 def foo; end

```

end

This will, of course, print “foo” forever.

As an aside, anyone else think method\_added should also receive a  
block of the method definition? E.g. this would be a “push” (less the  
infinite loop issue):

```
def self.method_added(name, &block)
  define_method(name, &block)
end

```

Thanks!  
T.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [November 13, 2007, 9:37pm UTC](https://www.ruby-forum.com/t/method-added-define-method-infinite-loop/120070/2 "2007-11-13T21:37:35Z")

</div>

On Nov 13, 2007, at 7:24 AM, Trans wrote:

> ```
> define_method(name, &block)
> end
> 
> ```
> 
> Thanks!  
> T.

cfp:~ \> cat a.rb  
class X  
class \<\< self  
def ignoring\_added\_methods  
ignoring\_added\_methods = @ignoring\_added\_methods  
@ignoring\_added\_methods = true  
yield  
ensure  
@ignoring\_added\_methods = ignoring\_added\_methods  
end

```
 def ignoring_added_methods?
   defined? @ignoring_added_methods and @ignoring_added_methods
 end

 def method_added name
   return if ignoring_added_methods?
   ignoring_added_methods do
     p name
     define_method(:bar){}
   end
 end

```

end

```
def foo
end

```

end

cfp:~ \> ruby a.rb  
:foo

a @ [http://codeforpeople.com/](http://codeforpeople.com/)

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [November 14, 2007, 4:13am UTC](https://www.ruby-forum.com/t/method-added-define-method-infinite-loop/120070/3 "2007-11-14T04:13:41Z")

</div>

On Nov 13, 3:36 pm, “ara.t.howard” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > ```
> > define_method(name)
> > 
> > ```
> > 
> > block of the method definition? E.g. this would be a “push” (less the  
> > class X  
> > defined? @ignoring\_added\_methods and @ignoring\_added\_methods
> 
> ```
> def foo
> end
> 
> ```
> 
> end
> 
> cfp:~ \> ruby a.rb  
> :foo

nice. i like the way you did that. thanks ara.

only question i have is about thread safety --could the instance var  
pose a potential problem with that?

T.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [November 14, 2007, 5:16am UTC](https://www.ruby-forum.com/t/method-added-define-method-infinite-loop/120070/4 "2007-11-14T05:16:49Z")

</div>

On Nov 13, 2007 8:24 AM, Trans [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> This will, of course, print “foo” forever.
> 
> As an aside, anyone else think method\_added should also receive a  
> block of the method definition? E.g. this would be a “push” (less the  
> infinite loop issue):
> 
> ```
> def self.method_added(name, &block)
> define_method(name, &block)
> end
> 
> ```

I might be missing something, but I cannot think of a practical use  
for that. It re-defined the method with the same name and  
content…Why?

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [November 14, 2007, 4:40am UTC](https://www.ruby-forum.com/t/method-added-define-method-infinite-loop/120070/5 "2007-11-14T04:40:36Z")

</div>

On Nov 13, 1:36 pm, “ara.t.howard” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> def ignoring_added_methods?
> defined? @ignoring_added_methods and @ignoring_added_methods
> end
> 
> ```

What was your motivation for the above code instead of simply  
def ignoring\_added\_methods?  
@ignoring\_added\_methods  
end

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [November 14, 2007, 6:44am UTC](https://www.ruby-forum.com/t/method-added-define-method-infinite-loop/120070/6 "2007-11-14T06:44:27Z")

</div>

On Nov 13, 2007, at 8:40 PM, Phrogz wrote:

> 

cfp:~ \> ruby -d -e ’ def foo() defined? @foo and @foo end; foo() ’

cfp:~ \> ruby -d -e ’ def foo() @foo end; foo() ’  
-e:1: warning: instance variable @foo not initialized

been trying to get the habit… it’s tough! 😉

cheers.

a @ [http://codeforpeople.com/](http://codeforpeople.com/)

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [November 14, 2007, 12:50pm UTC](https://www.ruby-forum.com/t/method-added-define-method-infinite-loop/120070/7 "2007-11-14T12:50:21Z")

</div>

On Nov 13, 11:16 pm, “Chris C.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > ```
> > end
> > 
> > ```
> 
> I might be missing something, but I cannot think of a practical use  
> for that. It re-defined the method with the same name and  
> content…Why?

I’m impractical ? 😉

meta-programming. In this instance, I was working on a Traits idea. I  
need to rename every method defined and keep track of it and replace  
it with a method that weaves together these renamed methods.

T.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [November 14, 2007, 6:49am UTC](https://www.ruby-forum.com/t/method-added-define-method-infinite-loop/120070/8 "2007-11-14T06:49:44Z")

</div>

On Nov 13, 2007, at 8:12 PM, Trans wrote:

> only question i have is about thread safety --could the instance var  
> pose a potential problem with that?

probably. maybe (untested):

cfp:~ \> cat a.rb  
class X  
class \<\< self  
def ignoring\_added\_methods  
ignoring\_added\_methods = @ignoring\_added\_methods  
@ignoring\_added\_methods = true  
yield  
ensure  
@ignoring\_added\_methods = ignoring\_added\_methods  
end

```
  def ignoring_added_methods?
    defined? @ignoring_added_methods and @ignoring_added_methods
  end

  def method_added name
    Thread.critical = true
    return if ignoring_added_methods?
    ignoring_added_methods do
      p name
      define_method(:bar){}
    end
  ensure
    Thread.critical = false
  end
end

 def foo
 end

```

end

cheers.

a @ [http://codeforpeople.com/](http://codeforpeople.com/)
