Inheriting variables, super, and "not super"?

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-read_article.php?articleId=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” :slight_smile:

    Hugh

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 :wink:

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” :slight_smile:

Dig to China! :slight_smile:

···

On Tuesday 09 December 2003 06:17 pm, Hugh Sasse Staff Elec Eng wrote:

Hi –

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.

Might you make use of instance variables of the classes themselves?
That might be a cleaner way to preserve state on a per-Class basis.
(I don’t know whether it fits in with the whole picture though.)

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?

I have a feeling that if you’re looking at two classes whose objects
have such different needs, it may be that the case for having one of
them be a subclass of the other is not all that strong.

Do you think a module-centered design would work better? You could
un-verticalize (?) the structure, and bring in what each class or even
each object needs.

David

···

On Wed, 10 Dec 2003, Hugh Sasse Staff Elec Eng wrote:


David A. Black
dblack@wobblini.net

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” :slight_smile:

   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

···

In message Pine.GSO.4.58.0312091649360.13219@neelix, Hugh Sasse Staff Elec Eng hgs@dmu.ac.uk writes


Ian - posting to a Newsgroup. Please remove everything to reply.

Hi –

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.

Might you make use of instance variables of the classes themselves?
That might be a cleaner way to preserve state on a per-Class basis.

That’s what I was thinking originally, but…

(I don’t know whether it fits in with the whole picture though.)

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

… they are not handed down to the children.
Maybe I shold be using accessor methods in the parent, which the
child will inherit, and I can constrain the access.

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 have a feeling that if you’re looking at two classes whose objects
have such different needs, it may be that the case for having one of
them be a subclass of the other is not all that strong.

The child classes respond to the same events as the ancestors, so
this is where the idea of inheritance is worth hanging on to, so ave
code duplication.

Do you think a module-centered design would work better? You could
un-verticalize (?) the structure, and bring in what each class or even
each object needs.

It is a nested structure except where the states need to mess with
other objects (GUI). I could include the parent to acheive this I suppose.
I think navigating this hierarchy will probably have about the same
complexity as I have now… I’ll give this more thought. Thank
you.

David

    Hugh
···

On Wed, 10 Dec 2003, David A. Black wrote:

On Wed, 10 Dec 2003, Hugh Sasse Staff Elec Eng wrote:

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” :slight_smile:

   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 :slight_smile:

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...
···

On Wed, 10 Dec 2003, Ian Hobson wrote:

In message Pine.GSO.4.58.0312091649360.13219@neelix, Hugh Sasse Staff > Elec Eng hgs@dmu.ac.uk writes

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 :wink:

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” :slight_smile:

Dig to China! :slight_smile:

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

    Hugh
···

On Wed, 10 Dec 2003, T. Onoma wrote:

On Tuesday 09 December 2003 06:17 pm, Hugh Sasse Staff Elec Eng wrote:

class Y
def y_init
p “in Y#y_init”
@y_var_2 = 0
end

def initialize
p “in Y#initialize”
@y_var = 0
y_init if initiator == Y
end

def initiator
self.class
end
end

class X < Y
def initialize
p "in X#initialize"
super
@x_var = 0
end
end

···


austin ziegler * austin@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.12.09
* 17.30.01

Hi Hugh,

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” :slight_smile:

   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 :slight_smile:

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

···

In message Pine.GSO.4.58.0312091953180.856@neelix, Hugh Sasse Staff Elec Eng hgs@dmu.ac.uk writes

On Wed, 10 Dec 2003, Ian Hobson wrote:

In message Pine.GSO.4.58.0312091649360.13219@neelix, Hugh Sasse Staff >> Elec Eng hgs@dmu.ac.uk writes


Ian - posting to a Newsgroup. Please remove everything to reply.

[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’

···

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 hgs@dmu.ac.uk writes

On Wed, 10 Dec 2003, Ian Hobson wrote:


Simon Strandgaard

Hi Hugh,

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
···

On Thu, 11 Dec 2003, Ian Hobson wrote:

In message Pine.GSO.4.58.0312091953180.856@neelix, Hugh Sasse Staff > Elec Eng hgs@dmu.ac.uk writes

On Wed, 10 Dec 2003, Ian Hobson wrote: