[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Using a class to extend a singleton?

Trans

3/1/2008 9:28:00 PM

Given:

class X
def yo=x; @yo=x; end
end

class Y
def yo!; puts @yo; end
end

x = X.new

Is there any way to extend x with Y's functionality (without going
back and changing the given code)? Eg.

>> x.yo="Hello World"
>> x.yo!
Hello World

T.



2 Answers

penguinofthegods

3/1/2008 9:41:00 PM

0

On 01/03/2008, Trans <transfire@gmail.com> wrote:
> Given:
>
> class X
> def yo=x; @yo=x; end
> end
>
> class Y
> def yo!; puts @yo; end
> end
>
> x = X.new
>
> Is there any way to extend x with Y's functionality (without going
> back and changing the given code)? Eg.
>
> >> x.yo="Hello World"
> >> x.yo!
> Hello World
>
>
> T.

class << x; Y.instance_methods.each {|m| define_method m, Y.method(:m)}; end

kind of. brings in Object onwards, though, but that's easy to fix.

-ehird

Trans

3/2/2008 6:36:00 AM

0



On Mar 1, 4:40 pm, "Elliott Hird" <penguinoftheg...@googlemail.com>
wrote:
> On 01/03/2008, Trans <transf...@gmail.com> wrote:
>
>
>
> > Given:
>
> > class X
> > def yo=x; @yo=x; end
> > end
>
> > class Y
> > def yo!; puts @yo; end
> > end
>
> > x = X.new
>
> > Is there any way to extend x with Y's functionality (without going
> > back and changing the given code)? Eg.
>
> > >> x.yo="Hello World"
> > >> x.yo!
> > Hello World
>
> > T.
>
> class << x; Y.instance_methods.each {|m| define_method m, Y.method(:m)}; end
>
> kind of. brings in Object onwards, though, but that's easy to fix.

Almost but not quite. You'd have to use Y.instance_method(:m) instead,
but then you get an error anyway because Y is not a subclass of X or
something to that effect.

I don't think there is any reasonable way. It's too bad. After the
discussion on MP, I decided to take a second shot at better
encapsulation of Facets. One idea was to just have a special way to
load them --if I could do the above that would work. But no go there
and nfortunately the traditional module namespaces doesn't work well
either --they can't handle aliasing of built-in methods and the double
module inclusion problem means it won't work for modules either.

Ruby really needs some fixing in this area!

To clarify the problem a faux example:

module Facets
module Comparable
alias_method :gte, :>= # no method to alias
def ccc; "ccc"; end
end
end

module Comparable
include Facets::Comparable
end

10.ccc #=> NoMethodError

T.