Forum: Ruby Adding methods to a singleton dynamically

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Mike A. (Guest)
on 2006-03-12 02:19
(Received via mailing list)
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
unknown (Guest)
on 2006-03-12 06:01
(Received via mailing list)
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)

"Ruby for Rails" chapters now available
from Manning Early Access Program! http://www.manning.com/books/black
unknown (Guest)
on 2006-03-12 06:38
(Received via mailing list)
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)

"Ruby for Rails" chapters now available
from Manning Early Access Program! http://www.manning.com/books/black
Mike A. (Guest)
on 2006-03-12 22:51
(Received via mailing list)
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
This topic is locked and can not be replied to.