Inheriting variables, super, and "not super"?

Discussion in 'Ruby' started by Hugh Sasse Staff Elec Eng, Dec 9, 2003.

  1. Is there a way in a method to say
    "ignore this if called as super"?

    I am trying to inherit variables from a superclass, but I may need
    them different in the subclass, so I can't use class variables.

    Instance variables are not passed on to subclasses, so to initialize
    them I need to call super within initialize...

    Also, at present, some of my initialization code sets up other
    things which make sense for an instance of that class, but not when
    I'm using an instance of a subclass.

    Is there an idiom like

    class Y < Z
    def initialize()
    @y_var = 0
    if self.class == Y
    y_init
    end
    end
    end


    class X < Y
    def initialize
    super
    @x_var = 0
    end
    end

    Or does this show I doing something horribly wrong?
    To quote Dave Thomas in
    http://www.codegeneration.net/tiki-...=9&PHPSESSID=a594d9ec9586b7a0e307f3f4f05e6a85

    "You can sense the code's resistance: things that should be easy
    turn our hard, and things that should be easy to change turn in to
    nightmares.[...] Quite often the problem lies not with the details of
    the code, but instead with something larger, such as the decision to
    use a particular technique. "

    This is what it feels like at the moment, but I can't see what else
    I should be using.

    For a bigger overview of my problem: I am trying to control an
    application with a Hierarchical State Machine, and I am trying to
    take advantage of the specialisation aspects of the class hierarchy
    to create the states. I had to provide a mechanism to navigate
    between states, so from that viewpoint the fit was imperfect. Now
    it looks worse.

    Any ideas? Apart from "If you're in a hole, stop digging" :)

    Hugh
    Hugh Sasse Staff Elec Eng, Dec 9, 2003
    #1
    1. Advertising

  2. Hugh Sasse Staff Elec Eng

    T. Onoma Guest

    On Tuesday 09 December 2003 06:17 pm, Hugh Sasse Staff Elec Eng wrote:
    >
    > Is there an idiom like
    >
    > class Y < Z
    > def initialize()
    > @y_var = 0
    > if self.class == Y
    > y_init
    > end
    > end
    > end
    >
    >
    > class X < Y
    > def initialize
    > super
    > @x_var = 0
    > end
    > end


    I'm not sure I understand you, but I'm interested in what it is you are
    attempting. Might you not use a redefinable responder method? (aka don't
    forget about our tusting duck typing ;)

    class Y < Z
    def initialize()
    @y_var = 0
    if initiator == Y
    y_init
    end
    end
    def initiator
    Y
    end
    end

    class X < Y
    def initialize
    super
    @x_var = 0
    end
    def initiator
    X
    end
    end

    T.

    > Any ideas? Apart from "If you're in a hole, stop digging" :)


    Dig to China! :)
    T. Onoma, Dec 9, 2003
    #2
    1. Advertising

  3. Hugh Sasse Staff Elec Eng

    Ian Hobson Guest

    In message <Pine.GSO.4.58.0312091649360.13219@neelix>, Hugh Sasse Staff
    Elec Eng <> writes
    >Is there a way in a method to say
    >"ignore this if called as super"?
    >

    [Big snip]
    >Any ideas? Apart from "If you're in a hole, stop digging" :)
    >
    > Hugh
    >
    >

    Hi Hugh,

    I think I have some idea of what you are trying to do, and perhaps some
    understanding of how you got into the wrong hole.

    Hint one - in trad programming you think of the data and how it needs to
    be manipulated. For OO Programming you think of the package of
    behaviours you need and create a class to behave in that way. Ignore the
    data - it will fall out of the other thinking.

    So. To your state machine.

    I would set up the state machine as a tree (or network if you must),
    where each node type is a different class. Inherit all (tree) nodes from
    a node type that knows how to manage its children.

    You can now walk the tree to change your state. At each node, you call a
    method to handle what needs doing at that state. The problem with this
    is that the code to handle all the types of state are scattered across
    lots of classes. Yuck!

    So in stead, you create a visitor class. This visits the node by sending

    node.acceptVisit(self) to the node it wants to visit, which simply
    calls

    aVisitor.hasVisitedNodeType(self)

    Where NodeType is different for each class of node. (This is called
    double despatch.)

    Then your visitor class has *all* the matching hasVisitedSomwhere
    methods, to handle all the actions you need. The hasVisitedSomewhere
    calls can have params to pass the information it needs, or it can pass
    self as shown, and then visitor uses node's accessors.

    This gives the visitor method all the info it needs to take its action,
    and decide where to go next.

    To use, you create a visitor and let it loose on the root node. It
    crawls over the tree, going its job. The tree neither knows nor cares
    who has visited.

    To do another job, create a new visitor class.

    Example - if the tree represented an expression, one visitor could
    report it in infix notation, another generate code to compute it and a
    third evaluate it directly, and a forth.... you get the idea.

    Regards

    Ian

    --
    Ian - posting to a Newsgroup. Please remove everything to reply.
    Ian Hobson, Dec 9, 2003
    #3
  4. On Wed, 10 Dec 2003, Ian Hobson wrote:

    > In message <Pine.GSO.4.58.0312091649360.13219@neelix>, Hugh Sasse Staff
    > Elec Eng <> writes
    > >Is there a way in a method to say
    > >"ignore this if called as super"?
    > >

    > [Big snip]
    > >Any ideas? Apart from "If you're in a hole, stop digging" :)
    > >
    > > Hugh
    > >
    > >

    > Hi Hugh,
    >
    > I think I have some idea of what you are trying to do, and perhaps some
    > understanding of how you got into the wrong hole.
    >
    > Hint one - in trad programming you think of the data and how it needs to
    > be manipulated. For OO Programming you think of the package of
    > behaviours you need and create a class to behave in that way. Ignore the
    > data - it will fall out of the other thinking.


    Yes, though I've not found the last bit comes so easily :)
    >
    > So. To your state machine.
    >
    > I would set up the state machine as a tree (or network if you must),
    > where each node type is a different class. Inherit all (tree) nodes from
    > a node type that knows how to manage its children.


    Yes. That's my basic design....
    >
    > You can now walk the tree to change your state. At each node, you call a
    > method to handle what needs doing at that state. The problem with this
    > is that the code to handle all the types of state are scattered across
    > lots of classes. Yuck!


    Yes, but the code to handle each state is as local to that state as
    possible, avoiding repetition of things in the ancestors. The
    complexity *is* difficult (for me) to manage. It sounds like you are
    saying this is not really a sad reflection of my ability to program,
    which is encouraging!

    >
    > So in stead, you create a visitor class. This visits the node by sending
    >
    > node.acceptVisit(self) to the node it wants to visit, which simply
    > calls
    >
    > aVisitor.hasVisitedNodeType(self)
    >
    > Where NodeType is different for each class of node. (This is called
    > double despatch.)


    I've encountered the term double dispatch in the context of nested
    case statements, I think. I can't see how these are two
    representations of the same thing... (That probably doesn't matter
    here, anyway) The need for both calls is that the visitor may need
    to tell the Node to give it some kinds of information, and to have
    the Node call a method on the visitor means they both do "Tell,
    Don't Ask"?
    (http://www.pragmaticprogrammer.com/developers/ppllc/papers/1998_05.html)
    Is that the idea? I've read about the visitor pattern but it has
    not really clicked, with me.

    >
    > Then your visitor class has *all* the matching hasVisitedSomwhere
    > methods, to handle all the actions you need. The hasVisitedSomewhere


    So it "knows" about all the events the system can respond to,....

    > calls can have params to pass the information it needs, or it can pass
    > self as shown, and then visitor uses node's accessors.


    ...and where to send them in the current state?

    >
    > This gives the visitor method all the info it needs to take its action,
    > and decide where to go next.
    >
    > To use, you create a visitor and let it loose on the root node. It
    > crawls over the tree, going its job. The tree neither knows nor cares
    > who has visited.
    >
    > To do another job, create a new visitor class.
    >
    > Example - if the tree represented an expression, one visitor could
    > report it in infix notation, another generate code to compute it and a
    > third evaluate it directly, and a forth.... you get the idea.


    So the visitor IS the current state? I'll have to re-read my [GOF]
    in the light of this....
    >
    > Regards
    >
    > Ian


    Hugh, pondering...
    Hugh Sasse Staff Elec Eng, Dec 9, 2003
    #4
  5. On Wed, 10 Dec 2003, T. Onoma wrote:

    > On Tuesday 09 December 2003 06:17 pm, Hugh Sasse Staff Elec Eng wrote:
    >
    > I'm not sure I understand you, but I'm interested in what it is you are
    > attempting. Might you not use a redefinable responder method? (aka don't
    > forget about our tusting duck typing ;)
    >
    > class Y < Z
    > def initialize()
    > @y_var = 0
    > if initiator == Y
    > y_init
    > end
    > end
    > def initiator
    > Y
    > end
    > end
    >
    > class X < Y

    [...]
    > def initiator
    > X
    > end
    > end
    >


    Yes, that might be better. I wonder if we can avoid having to
    repeat the method definition though?
    > T.
    >
    > > Any ideas? Apart from "If you're in a hole, stop digging" :)

    >
    > Dig to China! :)


    I think from here (.ac.uk) it would be Australia :)
    >


    Hugh
    Hugh Sasse Staff Elec Eng, Dec 9, 2003
    #5
  6. Hugh Sasse Staff Elec Eng

    Ian Hobson Guest

    Hi Hugh,

    In message <Pine.GSO.4.58.0312091953180.856@neelix>, Hugh Sasse Staff
    Elec Eng <> writes
    >On Wed, 10 Dec 2003, Ian Hobson wrote:
    >
    >> In message <Pine.GSO.4.58.0312091649360.13219@neelix>, Hugh Sasse Staff
    >> Elec Eng <> writes
    >> >Is there a way in a method to say
    >> >"ignore this if called as super"?
    >> >

    >> [Big snip]
    >> >Any ideas? Apart from "If you're in a hole, stop digging" :)
    >> >
    >> > Hugh
    >> >
    >> >

    >> Hi Hugh,
    >>
    >> I think I have some idea of what you are trying to do, and perhaps some
    >> understanding of how you got into the wrong hole.
    >>
    >> Hint one - in trad programming you think of the data and how it needs to
    >> be manipulated. For OO Programming you think of the package of
    >> behaviours you need and create a class to behave in that way. Ignore the
    >> data - it will fall out of the other thinking.

    >
    >Yes, though I've not found the last bit comes so easily :)
    >>
    >> So. To your state machine.
    >>
    >> I would set up the state machine as a tree (or network if you must),
    >> where each node type is a different class. Inherit all (tree) nodes from
    >> a node type that knows how to manage its children.

    >
    >Yes. That's my basic design....
    >>
    >> You can now walk the tree to change your state. At each node, you call a
    >> method to handle what needs doing at that state. The problem with this
    >> is that the code to handle all the types of state are scattered across
    >> lots of classes. Yuck!

    >
    >Yes, but the code to handle each state is as local to that state as
    >possible, avoiding repetition of things in the ancestors. The
    >complexity *is* difficult (for me) to manage. It sounds like you are
    >saying this is not really a sad reflection of my ability to program,
    >which is encouraging!
    >

    I didn't think it for a moment. State machines are hard!

    >>
    >> So in stead, you create a visitor class. This visits the node by sending
    >>
    >> node.acceptVisit(self) to the node it wants to visit, which simply
    >> calls
    >>
    >> aVisitor.hasVisitedNodeType(self)
    >>
    >> Where NodeType is different for each class of node. (This is called
    >> double despatch.)

    >
    >I've encountered the term double dispatch in the context of nested
    >case statements, I think. I can't see how these are two
    >representations of the same thing... (That probably doesn't matter
    >here, anyway)

    They are the same thing - the nested case statement is how it appears in
    procedural form.
    > The need for both calls is that the visitor may need
    >to tell the Node to give it some kinds of information, and to have
    >the Node call a method on the visitor means they both do "Tell,
    >Don't Ask"?
    >(http://www.pragmaticprogrammer.com/developers/ppllc/papers/1998_05.html)
    >Is that the idea? I've read about the visitor pattern but it has
    >not really clicked, with me.
    >

    Yes, but weakly. If the visitor simply told the node it has been
    visited, then the node would contain all the behaviour needed to act on
    that event.

    By moving all this code from the nodes to the visitor class, it becomes
    much easier to write. But it does go a bit against tell, don't ask.

    >>
    >> Then your visitor class has *all* the matching hasVisitedSomwhere
    >> methods, to handle all the actions you need. The hasVisitedSomewhere

    >
    >So it "knows" about all the events the system can respond to,....

    Yep - all in one source file.
    >
    >> calls can have params to pass the information it needs, or it can pass
    >> self as shown, and then visitor uses node's accessors.

    >
    >..and where to send them in the current state?

    I think so in this case. Where to go next can be decided by the
    visitor, the node or an external walker. To my mind, the flexibility
    offered by having the visitor class decide is well worth it.
    >
    >>
    >> This gives the visitor method all the info it needs to take its action,
    >> and decide where to go next.
    >>
    >> To use, you create a visitor and let it loose on the root node. It
    >> crawls over the tree, going its job. The tree neither knows nor cares
    >> who has visited.
    >>
    >> To do another job, create a new visitor class.
    >>
    >> Example - if the tree represented an expression, one visitor could
    >> report it in infix notation, another generate code to compute it and a
    >> third evaluate it directly, and a forth.... you get the idea.

    >
    >So the visitor IS the current state? I'll have to re-read my [GOF]
    >in the light of this....

    Yes - the visitor and its internal state, are the current state.

    Regards

    Ian

    --
    Ian - posting to a Newsgroup. Please remove everything to reply.
    Ian Hobson, Dec 10, 2003
    #6
  7. On Wed, 10 Dec 2003 20:09:10 +0000, Ian Hobson wrote:
    > In message <Pine.GSO.4.58.0312091953180.856@neelix>, Hugh Sasse Staff
    > Elec Eng <> writes
    >>On Wed, 10 Dec 2003, Ian Hobson wrote:

    [snip]
    >>So the visitor IS the current state? I'll have to re-read my [GOF]
    >>in the light of this....

    > Yes - the visitor and its internal state, are the current state.



    Yes visitor holds the current state.

    Its similar to sending a consultant into a big office, walking around from
    cubicle to cubicle and collecting data. Finaly he comes out of the office
    with the result.


    Yesterday I did some experiments with some filesystem ideas, where I am
    using visitor. You may want to check it out:
    http://rubyforge.org/cgi-bin/viewcvs/cgi/viewcvs.cgi/projects/experiments/file_system/?cvsroot=ros

    have a look at 'lookup.rb' and 'test_lookup.rb'

    --
    Simon Strandgaard
    Simon Strandgaard, Dec 10, 2003
    #7
  8. On Thu, 11 Dec 2003, Ian Hobson wrote:

    > Hi Hugh,
    >
    > In message <Pine.GSO.4.58.0312091953180.856@neelix>, Hugh Sasse Staff
    > Elec Eng <> writes
    > >On Wed, 10 Dec 2003, Ian Hobson wrote:
    > >
    > >> method to handle what needs doing at that state. The problem with this
    > >> is that the code to handle all the types of state are scattered across
    > >> lots of classes. Yuck!

    > >
    > >Yes, but the code to handle each state is as local to that state as
    > >possible, avoiding repetition of things in the ancestors. The
    > >complexity *is* difficult (for me) to manage. It sounds like you are
    > >saying this is not really a sad reflection of my ability to program,
    > >which is encouraging!
    > >

    > I didn't think it for a moment. State machines are hard!


    No, just how I felt about the experience. Yes, they seem to be
    difficult, even though they simplify things!
    >
    > >>

    > >I've encountered the term double dispatch in the context of nested
    > >case statements, I think. I can't see how these are two
    > >representations of the same thing... (That probably doesn't matter
    > >here, anyway)

    > They are the same thing - the nested case statement is how it appears in
    > procedural form.


    After reading my [GOF] and the web somewhat I see how these relate
    now.

    > > The need for both calls is that the visitor may need
    > >to tell the Node to give it some kinds of information, and to have
    > >the Node call a method on the visitor means they both do "Tell,
    > >Don't Ask"?

    [...]
    > >

    > Yes, but weakly. If the visitor simply told the node it has been
    > visited, then the node would contain all the behaviour needed to act on
    > that event.
    >
    > By moving all this code from the nodes to the visitor class, it becomes
    > much easier to write. But it does go a bit against tell, don't ask.
    >


    It is possibly like the visitor Telling the node Tell me what you
    want, rather than asking it "is this what you want"
    > >>
    > >> Then your visitor class has *all* the matching hasVisitedSomwhere
    > >> methods, to handle all the actions you need. The hasVisitedSomewhere

    > >
    > >So it "knows" about all the events the system can respond to,....

    > Yep - all in one source file.


    This was conterintuitive, normally you don't couple things that
    tightly. I think I understand it better now. My problem now is
    that I'm beginning to think I need triple dispatch. the state
    classes, the visitor (the application), and the GUI, with the GUI
    either as a collection of states or as another visitor to the state
    heirarchy.

    > >..and where to send them in the current state?

    > I think so in this case. Where to go next can be decided by the
    > visitor, the node or an external walker. To my mind, the flexibility
    > offered by having the visitor class decide is well worth it.
    > >
    > >So the visitor IS the current state? I'll have to re-read my [GOF]
    > >in the light of this....

    > Yes - the visitor and its internal state, are the current state.


    I think this pattern will be really useful elsewhere in this
    application as well, where all properties of each user must be
    processed in various ways.
    >
    > Regards
    >
    > Ian
    >

    Thank you,
    Hugh
    Hugh Sasse Staff Elec Eng, Dec 11, 2003
    #8
    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. Guest

    super.super.super how?

    Guest, Feb 19, 2005, in forum: Java
    Replies:
    24
    Views:
    10,740
    Darryl Pierce
    Feb 24, 2005
  2. Fernando Rodriguez

    Getting the super class via the super() function

    Fernando Rodriguez, Nov 21, 2003, in forum: Python
    Replies:
    2
    Views:
    708
    Bob Willan
    Nov 22, 2003
  3. Kerim Borchaev

    super. could there be a simpler super?

    Kerim Borchaev, Jan 15, 2004, in forum: Python
    Replies:
    4
    Views:
    466
    Michele Simionato
    Jan 15, 2004
  4. Ook
    Replies:
    3
    Views:
    474
  5. Replies:
    7
    Views:
    450
    Patricia Shanahan
    Apr 6, 2008
Loading...

Share This Page