# Adding methods to a singleton dynamically

**URL:** <https://www.ruby-forum.com/t/adding-methods-to-a-singleton-dynamically/80023>\
**Category:** Ruby\
**Created:** [March 12, 2006, 1:19am UTC](https://www.ruby-forum.com/t/adding-methods-to-a-singleton-dynamically/80023 "2006-03-12T01:19:54Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![exile](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/50afbb/32.png) [@exile](https://www.ruby-forum.com/u/exile)\
**Post date:** [March 12, 2006, 1:19am UTC](https://www.ruby-forum.com/t/adding-methods-to-a-singleton-dynamically/80023/1 "2006-03-12T01:19:54Z")

</div>

I’m building a view hierarchy from a file, and I would like it to add  
getter  
methods for every subview created. For example, I should be able to  
write:

window.bottom\_panel.save\_button.left = 20

I played around with singleton classes and define\_method, am I close? I  
wonder  
if it is illegal to do ‘class \<\< self end’ within a method - I get the  
error  
‘class definition in method body’

hierarchy.each do |key, value|  
view = Object::const\_get( key[1] ).new

class \<\< self end

self.class.class\_eval do  
define\_method( key[1] ) do  
return view  
end  
end  
end

hierarchy = {  
[:bottom\_panel, :Panel] =\> {  
[:save\_button, :Button] =\> {}  
}  
}

Thanks,  
Mike

---

<div class="post-metadata">

**Author:** ![exile](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/50afbb/32.png) [@exile](https://www.ruby-forum.com/u/exile)\
**Post date:** [March 12, 2006, 5:01am UTC](https://www.ruby-forum.com/t/adding-methods-to-a-singleton-dynamically/80023/2 "2006-03-12T05:01:56Z")

</div>

Hi –

On Sun, 12 Mar 2006, Mike A. wrote:

> view = Object::const\_get( key[1] ).new
> 
> class \<\< self end

I get a syntax error on that; I think you need a semi-colon after  
‘self’. However, even with the semi-colon, the expression doesn’t do  
anything. (It just opens a class definition block and then closes  
it.) Do you want to capture the singleton class? If so, you would  
do:

singleton\_class = (class \<\< self; self; end)

Inside the block, ‘self’ is the class itself. (And vote for your  
local RCR 231 🙂

> }  
> }

Does that last bit actually come first?

I haven’t quite grasped what you want to do (due to tiredness, I  
think), but maybe the above will help.

David

–  
David A. Black (removed\_email\_address@domain.invalid)  
Ruby Power and Light, LLC ([http://www.rubypowerandlight.com](http://www.rubypowerandlight.com))

“Ruby for Rails” chapters now available  
from Manning Early Access Program! [Ruby for Rails](http://www.manning.com/books/black)

---

<div class="post-metadata">

**Author:** ![exile](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/50afbb/32.png) [@exile](https://www.ruby-forum.com/u/exile)\
**Post date:** [March 12, 2006, 5:38am UTC](https://www.ruby-forum.com/t/adding-methods-to-a-singleton-dynamically/80023/3 "2006-03-12T05:38:05Z")

</div>

Hi –

On Sun, 12 Mar 2006, Mike A. wrote:

> view = Object::const\_get( key[1] ).new  
> hierarchy = {  
> [:bottom\_panel, :Panel] =\> {  
> [:save\_button, :Button] =\> {}  
> }  
> }

I just _know_ there’s a way to do this with inject… 🙂 But  
meanwhile, see if this is of any use. It’s a whole little  
self-contained simulation.

def cascade\_from\_hierarchy(base,hierarchy)  
label, kind = \*hierarchy.keys[0]  
rest = hierarchy.values[0]  
view = kind.new

(class \<\< base; self; end).class\_eval do  
define\_method(label) { view }  
end

cascade\_from\_hierarchy(view,rest) unless rest.empty?  
end

class Panel; end  
class Button; end  
class Window; end

window = Window.new  
hierarchy = {  
[:bottom\_panel, Panel] =\> {  
[:save\_button, Button] =\> {}  
}  
}

cascade\_from\_hierarchy(window,hierarchy)

p window.bottom\_panel.save\_button # #Button:0x1ceb58

**END**

## David

David A. Black (removed\_email\_address@domain.invalid)  
Ruby Power and Light, LLC ([http://www.rubypowerandlight.com](http://www.rubypowerandlight.com))

“Ruby for Rails” chapters now available  
from Manning Early Access Program! [Ruby for Rails](http://www.manning.com/books/black)

---

<div class="post-metadata">

**Author:** ![exile](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/50afbb/32.png) [@exile](https://www.ruby-forum.com/u/exile)\
**Post date:** [March 12, 2006, 9:51pm UTC](https://www.ruby-forum.com/t/adding-methods-to-a-singleton-dynamically/80023/4 "2006-03-12T21:51:21Z")

</div>

removed\_email\_address@domain.invalid wrote:

> I just _know_ there’s a way to do this with inject… 🙂 But  
> meanwhile, see if this is of any use. It’s a whole little  
> self-contained simulation.

Thanks, that does the job. I was a little unclear of how \<\< worked but  
now I  
get it.

Mike
