subclass a class in the namespace of the that subclass

Discussion in 'Ruby' started by Trans, Oct 22, 2008.

  1. Trans

    Trans Guest

    Ever get stuck on a problem, and then after staring at it for way too
    long, get disgusted b/c there is no way to do it the way you need to
    do it, and none of the workable alternatives quite cut it? Well,
    that's been my day.

    I know it may seem a bit off the wall. But I want to subclass a class
    that is also defined in the namespace of the subclass. In other words:

    class X < Y
    class Y
    end
    end

    Why do I want to do this? Because my library (X) consists of a few
    components, one of them being Y. And I want the end user of the
    library to use it by typing "X.new". Now, X is all but the same as Y,
    with only with some minor adjustments.

    Unfortunately for me there seems to be no way to do this without Ruby
    complaining of a superclass mismatch.

    In the end my alternatives appear to be:

    1) Use Z instead of X and fake it with X:

    module X
    def self.new
    Z.new
    end
    class Z < Y
    end
    end

    2) Delegate Y in X

    class X
    def initialize
    @y = Y.new
    end
    def method_missing ...
    end

    #1 sucks because I'm faking it --X isn't really new. And #2 sucks
    because it is nothing but a class wrapped around a single instance
    variable --a complete waste of resources.

    I imagine there is a tricky dynamic coding way to do it, but that will
    screw up my RDocs.

    Well, I don't see any solution for it --if you have one I'll be
    amazed. But at least I got to vent.

    T.
     
    Trans, Oct 22, 2008
    #1
    1. Advertising

  2. Trans

    Pit Capitain Guest

    2008/10/22 Trans <>:
    > I know it may seem a bit off the wall. But I want to subclass a class
    > that is also defined in the namespace of the subclass. In other words:
    >
    > class X < Y
    > class Y
    > end
    > end


    Tom, that's easy if you split the creation of the classes from naming them:

    y = Class.new

    class X < y
    end

    X::Y = y

    p X.ancestors # => [X, X::Y, Object, Kernel]

    Regards,
    Pit
     
    Pit Capitain, Oct 22, 2008
    #2
    1. Advertising

  3. Hi --

    On Thu, 23 Oct 2008, Trans wrote:

    > Ever get stuck on a problem, and then after staring at it for way too
    > long, get disgusted b/c there is no way to do it the way you need to
    > do it, and none of the workable alternatives quite cut it? Well,
    > that's been my day.
    >
    > I know it may seem a bit off the wall. But I want to subclass a class
    > that is also defined in the namespace of the subclass. In other words:
    >
    > class X < Y
    > class Y
    > end
    > end
    >
    > Why do I want to do this? Because my library (X) consists of a few
    > components, one of them being Y. And I want the end user of the
    > library to use it by typing "X.new". Now, X is all but the same as Y,
    > with only with some minor adjustments.
    >
    > Unfortunately for me there seems to be no way to do this without Ruby
    > complaining of a superclass mismatch.


    How about this?

    c = Class.new
    X = Class.new(c)
    X.class_eval do
    const_set("Y",c)
    end

    p X::Y # X::Y
    p X.superclass # X::Y
    p X.superclass == X::Y # true

    (I used const_set instead of Y = c because that created a top-level
    constant.)

    I don't know what you need it for but if that helps, there it is :)


    David

    --
    Rails training from David A. Black and Ruby Power and Light:
    Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
    Advancing with Rails January 19-22 Fort Lauderdale, FL *
    * Co-taught with Patrick Ewing!
    See http://www.rubypal.com for details and updates!
     
    David A. Black, Oct 22, 2008
    #3
  4. Trans

    James Coglan Guest

    [Note: parts of this message were removed to make it a legal post.]

    >
    >
    > class X < Y
    > class Y
    > end
    > end




    Could you make Y a module?

    class X
    module Y
    # methods
    end
    include Y
    # more methods
    end

    Or, if Y needs to be a class:

    class X
    module M
    # methods for Y
    end
    class Y; include M; end # Y implements nothing itself
    include M
    # add methods to X here
    end

    That way, X and Y both inherit from M, but Y is basically an empty class
    that acts as an instantiable version of module M.

    --
    James Coglan
    http://blog.jcoglan.com
    http://github.com/jcoglan
     
    James Coglan, Oct 22, 2008
    #4
  5. Trans

    Trans Guest

    On Oct 22, 6:08=A0pm, "Pit Capitain" <> wrote:

    > Tom, that's easy if you split the creation of the classes from naming the=

    m:
    >
    > =A0 y =3D Class.new
    >
    > =A0 class X < y
    > =A0 end
    >
    > =A0 X::Y =3D y
    >
    > =A0 p X.ancestors =A0# =3D> [X, X::Y, Object, Kernel]


    Thanks Pit (and David),

    The solution is cleaner than I thought it would be actually --that's
    good, but I avoided this direction myself b/c of how it would effect
    RDocs. RDoc sees X::Y as just a constant and not a class. Yea, I know
    I shouldn't code to the rdocs, but unfortunately RDocs are important.
    Maybe something to consider for improving Rdocs in the future, a way
    to force it to recognize certain dynamic designs as particular
    constructs. But I digress...

    Another option that occurred to me, I could make X the primary class
    and subclass it as Y even though it would mean a couple
    remove_methods. Still not ideal but perhaps close enough.

    T.
     
    Trans, Oct 23, 2008
    #5
  6. Trans

    Trans Guest

    On Oct 22, 6:09=A0pm, "David A. Black" <> wrote:
    > Hi --
    >
    >
    >
    > On Thu, 23 Oct 2008, Trans wrote:
    > > Ever get stuck on a problem, and then after staring at it for way too
    > > long, get disgusted b/c there is no way to do it the way you need to
    > > do it, and none of the workable alternatives quite cut it? Well,
    > > that's been my day.

    >
    > > I know it may seem a bit off the wall. But I want to subclass a class
    > > that is also defined in the namespace of the subclass. In other words:

    >
    > > =A0class X < Y
    > > =A0 =A0class Y
    > > =A0 =A0end
    > > =A0end

    >
    > > Why do I want to do this? Because my library (X) consists of a few
    > > components, one of them being Y. And I want the end user of the
    > > library to use it by =A0typing "X.new". Now, X is all but the same as Y=

    ,
    > > with only with some minor adjustments.

    >
    > > Unfortunately for me there seems to be no way to do this without Ruby
    > > complaining of a superclass mismatch.

    >
    > How about this?
    >
    > c =3D Class.new
    > X =3D Class.new(c)
    > X.class_eval do
    > =A0 =A0const_set("Y",c)
    > end
    >
    > p X::Y =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0# X::Y
    > p X.superclass =A0 =A0 =A0 =A0 =A0 =A0# X::Y
    > p X.superclass =3D=3D X::Y =A0 =A0# true
    >
    > (I used const_set instead of Y =3D c because that created a top-level
    > constant.)


    (see my response to the Captain)

    > I don't know what you need it for but if that helps, there it is :)


    Ok. Well I'll spill... I've been working on an "uber" commandline
    parser:

    class Usage < Command
    class Command
    class Option
    class Argument

    Thus Usage is the main toplevel command. A command can have
    subcommands, options, arguments... so forth and so on.

    T.
     
    Trans, Oct 23, 2008
    #6
  7. Trans

    Trans Guest

    On Oct 22, 6:30=A0pm, "James Coglan" <> wrote:
    > > =A0class X < Y
    > > =A0 =A0class Y
    > > =A0 =A0end
    > > =A0end

    >
    > Could you make Y a module?
    >
    > class X
    > =A0 module Y
    > =A0 =A0 # methods
    > =A0 end
    > =A0 include Y
    > =A0 # more methods
    > end
    >
    > Or, if Y needs to be a class:
    >
    > class X
    > =A0 module M
    > =A0 =A0 # methods for Y
    > =A0 end
    > =A0 class Y; include M; end # Y implements nothing itself
    > =A0 include M
    > =A0 # add methods to X here
    > end
    >
    > That way, X and Y both inherit from M, but Y is basically an empty class
    > that acts as an instantiable version of module M.


    That's probably the most justifiable approach under the circumstances
    (though lately I've been shying away a bit from modules[1]), most any
    other time I'd likely do that. But in this case, it just doesn't seem
    to fit. I have to name this module something (what?) and then I'll
    have to explain why it even exists, in the docs, and so on --it feels
    too "bolted on".

    I'll just have to think on it more.

    Thanks,
    T.

    [1] Yes, Austin I've learned a thing or two from you. :)
     
    Trans, Oct 23, 2008
    #7
  8. Trans

    ara.t.howard Guest

    On Oct 22, 2008, at 3:53 PM, Trans wrote:

    > I know it may seem a bit off the wall. But I want to subclass a class
    > that is also defined in the namespace of the subclass. In other words:
    >
    > class X < Y
    > class Y
    > end
    > end
    >
    > Why do I want to do this? Because my library (X) consists of a few
    > components, one of them being Y. And I want the end user of the
    > library to use it by typing "X.new". Now, X is all but the same as Y,
    > with only with some minor adjustments.
    >
    > Unfortunately for me there seems to be no way to do this without Ruby
    > complaining of a superclass mismatch.



    invert:

    cfp:~ > cat a.rb
    class Y
    def Y.foo() 42 end

    class ::X < Y
    Y = Y
    end
    end

    p(Y == X::Y)

    p X.foo


    cfp:~ > ruby a.rb
    true
    42



    a @ http://codeforpeople.com/
    --
    we can deny everything, except that we have the possibility of being
    better. simply reflect on that.
    h.h. the 14th dalai lama
     
    ara.t.howard, Oct 23, 2008
    #8
  9. 2008/10/22 Trans <>:
    > Ever get stuck on a problem, and then after staring at it for way too
    > long, get disgusted b/c there is no way to do it the way you need to
    > do it, and none of the workable alternatives quite cut it? Well,
    > that's been my day.
    >
    > I know it may seem a bit off the wall. But I want to subclass a class
    > that is also defined in the namespace of the subclass. In other words:
    >
    > class X < Y
    > class Y
    > end
    > end


    Aren't you introducing a circular dependency here? I'd try to avoid
    that. These things cause all sorts of bad effects (e.g. headache for
    me). Even if it is possible if feels most awkward to me.

    Kind regards

    robert

    --
    remember.guy do |as, often| as.you_can - without end
     
    Robert Klemme, Oct 23, 2008
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jstorta
    Replies:
    3
    Views:
    475
    jstorta
    Feb 20, 2006
  2. Peng Yu
    Replies:
    0
    Views:
    661
    Peng Yu
    Sep 14, 2008
  3. S.Volkov
    Replies:
    2
    Views:
    242
    S.Volkov
    Mar 12, 2006
  4. J2M
    Replies:
    3
    Views:
    110
  5. Fab

    Subclass of subclass

    Fab, Aug 9, 2012, in forum: C++
    Replies:
    0
    Views:
    415
Loading...

Share This Page