Where's the best place to dynamically add singleton method?

Hi,

If I've got a simple bit of initialisation code

    def initialize( blah )
      @listener = Blah.new blah
    end

and I'd like to add a singleton method to instance (because I don't want to monkey patch the Blah library) where's the best place to do that? I know I could do:

    def initialize( blah )
      @listener = Blah.new blah
      def @listener.my_mental_method
        self.give_it_up! "quickly"
      end
    end

but is this a good place to do it, or is there something more eloquent/perfomant? I'd like all instances, wherever they are created, to have this method, so is there a better way altogether?

Just wondering.

Regards,
Iain

Hi,

If I've got a simple bit of initialisation code

def initialize( blah )
@listener = Blah.new blah
end

and I'd like to add a singleton method to instance (because I don't want to monkey patch the Blah library) where's the best place to do that? I know I could do:

def initialize( blah )
@listener = Blah.new blah
def @listener.my_mental_method
self.give_it_up! "quickly"

No self needed here.

 end

end

but is this a good place to do it, or is there something more eloquent/perfomant? I'd like all instances, wherever they are created, to have this method, so is there a better way altogether?

First of all, I'd place the method in a module so you have less
definitions around. Then I'd extend all instances with that module.
That also makes for easy addition of more methods.

module BlahExt
  def your_mental_method
    give_it_up! 'rather sooner than later'
  end
end

The automatic part could be handled by changing Bar's #new:

class <<Blah
  alias _new new

  def new(*a,&b)
    _new(*a,&b).extend BlahExt
  end
end

Note that this does not deal with inheritance nicely. For that you
could do something similar with Bar's #initialize instead of #new.

If you do not need a global automatic I'd simply stick with

   def initialize( blah )
     @listener = Blah.new(blah).extend BlahExt
   end

Kind regards

robert

···

On Thu, Apr 28, 2011 at 3:58 PM, Iain Barnett <iainspeed@gmail.com> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

I think you can achieve functionality that you desire by using mixins,
modules and include statement... like this

module CoolMethods
  def my_mental_method
     ....
  end
end

class UnfortunateUserOfCoolMethod

   include CoolMethods
   ....

end

Also if you need method on a class you can use extend intstead of
include....

Best Regards,

Kresimir Bojcic

···

On Thu, Apr 28, 2011 at 3:58 PM, Iain Barnett <iainspeed@gmail.com> wrote:

Hi,

If I've got a simple bit of initialisation code

   def initialize( blah )
     @listener = Blah.new blah
   end

and I'd like to add a singleton method to instance (because I don't want to
monkey patch the Blah library) where's the best place to do that? I know I
could do:

   def initialize( blah )
     @listener = Blah.new blah
     def @listener.my_mental_method
       self.give_it_up! "quickly"
     end
   end

but is this a good place to do it, or is there something more
eloquent/perfomant? I'd like all instances, wherever they are created, to
have this method, so is there a better way altogether?

Just wondering.

Regards,
Iain

Thanks to you both for the input. Sorry I didn't reply sooner but was snowed under with other things and wanted to think about it and do a bit of research. I've been reading a lot more on what's going on with details of the Ruby inheritance model, all that stuff in the background that I was getting along with fine without till now (which I think is a testament to the language), and your answers helped.

Due to this I refactored things quite significantly so I've ended up not using this directly, but I've gone further for it.

Much appreciated

Regards,
Iain

···

On 28 Apr 2011, at 15:09, Robert Klemme wrote:

On Thu, Apr 28, 2011 at 3:58 PM, Iain Barnett <iainspeed@gmail.com> wrote:

Hi,

If I've got a simple bit of initialisation code

   def initialize( blah )
     @listener = Blah.new blah
   end

and I'd like to add a singleton method to instance (because I don't want to monkey patch the Blah library) where's the best place to do that? I know I could do:

   def initialize( blah )
     @listener = Blah.new blah
     def @listener.my_mental_method
       self.give_it_up! "quickly"

No self needed here.

     end
   end

but is this a good place to do it, or is there something more eloquent/perfomant? I'd like all instances, wherever they are created, to have this method, so is there a better way altogether?

First of all, I'd place the method in a module so you have less
definitions around. Then I'd extend all instances with that module.
That also makes for easy addition of more methods.

module BlahExt
def your_mental_method
   give_it_up! 'rather sooner than later'
end
end

The automatic part could be handled by changing Bar's #new:

class <<Blah
alias _new new

def new(*a,&b)
   _new(*a,&b).extend BlahExt
end
end

Note that this does not deal with inheritance nicely. For that you
could do something similar with Bar's #initialize instead of #new.

If you do not need a global automatic I'd simply stick with

  def initialize( blah )
    @listener = Blah.new(blah).extend BlahExt
  end

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

On 28 Apr 2011, at 15:15, Kresimir Bojcic wrote:

I think you can achieve functionality that you desire by using mixins,
modules and include statement... like this

module CoolMethods
def my_mental_method
    ....
end
end

class UnfortunateUserOfCoolMethod

  include CoolMethods
  ....

end

Also if you need method on a class you can use extend intstead of
include....

Best Regards,

Kresimir Bojcic

www.kresimirbojcic.com

I'm glad to hear that we could help you. Thank you for letting us know!

Kind regards

  robert

···

On 06.05.2011 22:15, Iain Barnett wrote:

Thanks to you both for the input. Sorry I didn't reply sooner but was
snowed under with other things and wanted to think about it and do a
bit of research. I've been reading a lot more on what's going on with
details of the Ruby inheritance model, all that stuff in the
background that I was getting along with fine without till now (which
I think is a testament to the language), and your answers helped.

Due to this I refactored things quite significantly so I've ended up
not using this directly, but I've gone further for it.

Much appreciated

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/