One more question on inheritance -- using methods in extending class
Hi all,
Although inheritance/polymorphism were made a bit more clear to me yesterday with my other thread, I still have a question, and this time it's specific.
I'm trying to work with an inheritance hierarchy that looks like this:
LLEIceObject
DataSetextends LLEIceObject
Imageextends Dataset
RawImageextends Image
I have a method signature that looks like this:
publicvoid reportEvent(LLEIceObject aEvent,byte[] aData)
This method will send me an image. There is apparently data about the image in the RawImage class, as it has some fields like bitsPerPixel, imageColorSpace, etc.
I need to access the fields in RawImage; these should be populated somehow through aEvent (or so I'm told) when the data returns.
I don't really get how, but what I want to know is how to make a RawImage from that LLEIceObject so I can access the fields. Do I have to cast something or do something crazy? I've tried:
aEvent =new RawImage();
System.out.println("Colorspace: " + blah.imageColorSpace);
System.out.println("bitsPerPixel: " + blah.bitsPerPixel);
This doesn't compile, and it tells me:
[javac] /u/dgresh/dev/ice/LLEIce/src/lle/ice/LLEIFEvent.java:26: cannot find symbol
[javac] symbol : variable imageColorSpace
[javac] location: class LLE.LLEIce.LLEIceObject
[javac] System.out.println("Colorspace: " + blah.imageColorSpace);
[javac] ^
[javac] /u/dgresh/dev/ice/LLEIce/src/lle/ice/LLEIFEvent.java:27: cannot find symbol
[javac] symbol : variable bitsPerPixel
[javac] location: class LLE.LLEIce.LLEIceObject
[javac] System.out.println("bitsPerPixel: " + blah.bitsPerPixel);
[javac]^
[javac] 2 errors
Am I missing something here, or is the design not right for what I'm trying to do?
Thanks
[2157 byte] By [
Djaunla] at [2007-11-27 10:57:05]

Where are the variables imageColorSpace and bitsPerPixel and blah defined?
Message was edited by:
manuel.leiria
> Where is the variable imageColorSpace defined?
imageColorSpace and bitsPerPixel are both defined in RawImage.
and what is "blah"'s type?
> and what is "blah"'s type?
Oh sorry, I forgot to change the variable name.
blah should be aEvent.
> aEvent = new RawImage();
> System.out.println("Colorspace: " + blah.imageColorSpace);
> System.out.println("bitsPerPixel: " + blah.bitsPerPixel);
What is blah?
> and what is "blah"'s type?
Well, the error message says it's a LLEIceObject:[javac] /u/dgresh/dev/ice/LLEIce/src/lle/ice/LLEIFEvent.java:26: cannot find symbol
[javac] symbol : variable imageColorSpace
[javac] location: class LLE.LLEIce.LLEIceObject
[javac] System.out.println("Colorspace: " + blah.imageColorSpace);
[javac] ^
> What is blah?
See above. I really wish I could edit my first post.
> blah should be aEvent.
The error message seems to insist that blah (or whatever) if of type LLEIceObject, not RawImage!
Accessing fields in a superclass is a hideous idea. Whenever I see a protected field, it sends shivers down my spine. Same pretty much goes for protected methods, come to think of it! In both cases - and indeed with concrete inheritance in general - you've got a dependency on a concrete class, a dependency on it's implementation details. This is why I prefer object composition.
For example, is an Image really a special kind of DataSet, or does an Image have a DataSet? You could model it either way, but the has-a relationship avoids the concrete dependencies
I can't count the number of times I've seen perfectly good code simply stop working, because some superclass 4 steps up the hierarchy changed one of it's protected methods. Nasty
> > and what is "blah"'s type?
>
> Oh sorry, I forgot to change the variable name.
>
> blah should be aEvent.
So after having checked that aEvent is an instance of RawImage (by using instanceof), you can cast it, and therefore access RawImage specific members.
Downcasting (from a parent type to a child type) is allowed if and ONLY if the object in question has a runtime instance of that type. It may appear as an LLEIceObject, but it is actually a RawImage that is being used as that. On the other hand, if you are sent an "Image" object as an LLEIceObject and try to cast that to a RawImage object, you will get an exception.
if(aEvent instanceof RawImage) { //Make sure it is actually a RawImage
RawImage img = (RawImage)aEvent;
//Do stuff with your raw image.
} else { //These are not the droids your looking for...
//...
}
> Accessing fields in a superclass is a hideous idea.
> Whenever I see a protected field, it sends shivers
> down my spine. Same pretty much goes for protected
> methods, come to think of it! In both cases - and
> indeed with concrete inheritance in general - you've
> got a dependency on a concrete class, a dependency on
> it's implementation details. This is why I prefer
> object composition.
>
> For example, is an Image really a special kind of
> DataSet, or does an Image have a DataSet? You
> could model it either way, but the has-a relationship
> avoids the concrete dependencies
>
> I can't count the number of times I've seen perfectly
> good code simply stop working, because some
> superclass 4 steps up the hierarchy changed one of
> it's protected methods. Nasty
What's a code monkey to do? Refuse to use frameworks that indulge in derivation? Does that mean I can't use Swing? What should I use in its place?
> > Accessing fields in a superclass is a hideous
> idea.
> > Whenever I see a protected field, it sends shivers
> > down my spine. Same pretty much goes for protected
> > methods, come to think of it! In both cases - and
> > indeed with concrete inheritance in general -
> you've
> > got a dependency on a concrete class, a dependency
> on
> > it's implementation details. This is why I prefer
> > object composition.
> >
> > For example, is an Image really a special kind of
> > DataSet, or does an Image have a DataSet?
> You
> > could model it either way, but the has-a
> relationship
> > avoids the concrete dependencies
> >
> > I can't count the number of times I've seen
> perfectly
> > good code simply stop working, because some
> > superclass 4 steps up the hierarchy changed one of
> > it's protected methods. Nasty
>
> What's a code monkey to do? Refuse to use frameworks
> that indulge in derivation? Does that mean I can't
> use Swing? What should I use in its place?
Not in the least, big daddy. But one can avoid writing such code
> public void reportEvent(LLEIceObject aEvent, byte[] aData) {
>...
>aEvent = new RawImage();
This is one of the worst things to do: you simply get rid of the parameter, and use a brand new object instead.
Assigning a parameter with a new value is generally confusing. Parameters should be made final unless there is a good reason not to.
> Not in the least, big daddy. But one can avoid writing such code
Big Daddy?! Pay no attention to the portly man behind the curtains!
Anyhowdy, I take your point, although I don't think the OP wrote this
hierarchy. It sounds to me like he's just trying to figure out how to
use a package someone tossed to him.
> > > Accessing fields in a superclass is a hideous
> > idea.
> > > Whenever I see a protected field, it sends
> shivers
> > > down my spine. Same pretty much goes for
> protected
> > > methods, come to think of it! In both cases -
> and
> > > indeed with concrete inheritance in general -
> > you've
> > > got a dependency on a concrete class, a
> dependency
> > on
> > > it's implementation details. This is why I
> prefer
> > > object composition.
> > >
> > > For example, is an Image really a special kind
> of
> > > DataSet, or does an Image have a DataSet?
> > You
> > > could model it either way, but the has-a
> > relationship
> > > avoids the concrete dependencies
> > >
> > > I can't count the number of times I've seen
> > perfectly
> > > good code simply stop working, because some
> > > superclass 4 steps up the hierarchy changed one
> of
> > > it's protected methods. Nasty
> >
> > What's a code monkey to do? Refuse to use
> frameworks
> > that indulge in derivation? Does that mean I can't
> > use Swing? What should I use in its place?
>
> Not in the least, big daddy. But one can avoid
> writing such code
I usually find it is generally OK as long as the superX's do as little as possible. I have had instances where I have several classes (A, B, C, D and E) which all implement interface F. In my code, they are all handled as being of type F until they need to be casted to one of the other interface types. IMHO, it's ok to do because F's declaration looks like this:
interface F {}
Basically it just saves time on the if statements.
> Accessing fields in a superclass is a hideous idea.
> Whenever I see a protected field, it sends shivers
> down my spine. Same pretty much goes for protected
> methods, come to think of it!
Protected methods do have their place, albeit rarely. Protected fields (other than maybe static final) are the devil.
jverda at 2007-7-29 12:06:54 >

Thanks for all the replies. I have followed your advice, and my code now looks like this:
aEvent = new RawImage();
if (aEvent instanceof RawImage) {
RawImage img = (RawImage)aEvent;
System.out.println("Colorspace: " + img.imageColorSpace);
System.out.println("bitsPerPixel: " + img.bitsPerPixel);
} else {
System.out.println("You fail."); // yea yea bad error messages
}
Unfortunately, the fields in RawImage seem to not be populated. Is this because of the new instance?
>Is this because of the new instance?
That would be a very good and accurate guess.
> This is one of
> the worst things to do: you simply get rid of the
> parameter, and use a brand new object instead.
> Assigning a parameter with a new value is generally
> confusing. Parameters should be made final unless
> there is a good reason not to.
Ah, I guess that'd be my problem. If I remove the "new RawImage()" statement, my conditional executes the else statement however, and I cannot cast to RawImage without creating a new instance, or it will throw a ClassCastException.
Is there a way to do this while still having the RawImage fields populated?
> > Accessing fields in a superclass is a hideous
> idea.
> > Whenever I see a protected field, it sends shivers
> > down my spine. Same pretty much goes for protected
> > methods, come to think of it!
>
> Protected methods do have their place, albeit rarely.
> Protected fields (other than maybe static final) are
> the devil.
Note pretty much :-) I use 'em too, now and again
> > This is one of
> > the worst things to do: you simply get rid of the
> > parameter, and use a brand new object instead.
> > Assigning a parameter with a new value is
> generally
> > confusing. Parameters should be made final unless
> > there is a good reason not to.
>
> Ah, I guess that'd be my problem. If I remove the
> "new RawImage()" statement, my conditional executes
> the else statement however, and I cannot cast to
> RawImage without creating a new instance, or it will
> throw a ClassCastException.
>
> Is there a way to do this while still having the
> RawImage fields populated?
That means that the parameter is not a RawImage, and therefore has probably no imageColorSpace nor bitsPerPixel field.
If it executes the else statement, it means that aEvent's runtime class was not RawImage in the first place. Check where it is calling your method and make sure it is actually passing a RawImage.
> > Not in the least, big daddy. But one can avoid
> writing such code
>
> Big Daddy?! Pay no attention to the portly man behind
> the curtains!
> Anyhowdy, I take your point, although I don't think
> the OP wrote this
> hierarchy. It sounds to me like he's just trying to
> figure out how to
> use a package someone tossed to him.
I did not write this. I just have to work with it. Fun times.
> What's a code monkey to do? Refuse to
> use frameworks that indulge in derivation?
> Does that mean I can't use Swing? What
> should I use in its place?
Callin' me a code monkey eh? I'll have your head! Just kidding.
> aEvent = new RawImage();
> if (aEvent instanceof RawImage) {
> RawImage img = (RawImage)aEvent;
> System.out.println("Colorspace: " + img.imageColorSpace);
> System.out.println("bitsPerPixel: " + img.bitsPerPixel);
> } else {
> System.out.println("You fail."); // yea yea bad error messages
> }
Pardon my French acronyms, but WTF?! Why are you testing with instanceof
when you created the object on the previous line?! I think you're making
some basic mistakes in logic here. I'm guessing (guessing!) this code
is in the report method you mentioned before. Shouldn't it be like this?
public void reportEvent(LLEIceObject aEvent, byte[] aData) {
if (aEvent instanceof RawImage) {
RawImage rawImage = (RawImage) aEvent;
...
} else {
...
}
}
> > aEvent = new RawImage();
> > if (aEvent instanceof RawImage) {
> > RawImage img = (RawImage)aEvent;
> > System.out.println("Colorspace: " +
> img.imageColorSpace);
> > System.out.println("bitsPerPixel: " +
> img.bitsPerPixel);
> > } else {
> > System.out.println("You fail."); // yea yea bad
> error messages
> > }
>
> Pardon my French acronyms, but WTF?! Why are you
> testing with instanceof
> when you created the object on the previous line?! I
> think you're making
> some basic mistakes in logic here. I'm guessing
> (guessing!) this code
> is in the report method you mentioned before.
> Shouldn't it be like this?
> > public void reportEvent(LLEIceObject aEvent, byte[]
> aData) {
>if (aEvent instanceof RawImage) {
>RawImage rawImage = (RawImage) aEvent;
>...
> } else {
>...
> }
> }
>
Yeah we have already established that creating it as a new instance is a bad idea.
and I believe "WTS" would be a better French acronym; as in, "What are your Terms of Surrender?"
Message was edited by:
jGardner
> Pardon my French acronyms, but WTF?! Why are you
> testing with instanceof
> when you created the object on the previous line?!
Hah, I actually laughed at myself when I realized how stupid this was.
@jGardner: the Object that is given to the method is conveniently passed through C++ server side code that I can't follow.
> Yeah we have already established that creating it as a new instance is a bad idea.
The posts are coming fast an furious, and I'm slow!
Addendum: why not check to see what class *is* being passed?
public void reportEvent(LLEIceObject aEvent, byte[] aData) {
if (aEvent instanceof RawImage) {
RawImage rawImage = (RawImage) aEvent;
...
} else {
System.out.println("I see this instead " + aEvent.getClass());
}
}
> and I believe "WTS" would be a better French acronym; as in, "What are your Terms of Surrender?"
The French are a proud people, with many, many kinds of cheese. I suggest you state that you are only joking!
> Addendum: why not check to see what class *is* being passed?
You mean... debugging ? Woah ! ; )
Well...
If you generalize a Monkey as a Mammal, and decide to call it a Monkey later, that is ok. On the other hand, if you generalize a Mouse as a Mammal, and try to call the Mouse a Monkey later, the Mouse will probably be quite indignant.
In this case, if your LLEIceObject were, say, an instance of Image, by passing it to this method you are generalizing it as an LLEIceObject. Now you are trying to call the Image a RawImage, and, even though the RawImage may have evolved from the Image, it still won't let you.
The only way you can go from an Object to an LLEIceObject to a RawImage is if your original Object was a RawImage in the first place.
HAIL DARWIN!
> > Addendum: why not check to see what class *is*
> being passed?
>
> You mean... debugging ? Woah ! ; )
Heresy! My code always works properly the first time!
Yar.
Ok guys, I've figured out the Class being passed and the hierarchy. Are you ready for this?
DataSetList is being passed. DataSetList extends LLEIceObject. Image does NOT extend DataSetList. Therefore, must I cast DataSetList to LLEIceObject, then cast that to RawImage?
I tried this:
if (aEvent instanceof DataSetList) {
System.out.println("You succeed.");
LLEIceObject blah = (LLEIceObject)aEvent;
RawImage img = (RawImage)blah;
System.out.println("Colorspace: " + img.imageColorSpace);
System.out.println("bitsPerPixel: " + img.bitsPerPixel);
} else {
System.out.println("You fail.");
}
It throws a ClassCastException (a.k.a. DatShitDontFitException).
Judging by my 9 new messages, seems I have to catch up on a lot of posts that I've missed while trying to test this.
> It throws a ClassCastException (a.k.a.
> DatShitDontFitException).
:-)
You cannot cast something into something it is not.
If aEvent is a DataSetList, then you can cast it to DataSetList or any of the DataSetList 's superclasses, or whatever interface DataSetList implements. Nothing more.
Also, DataSetList has an array of DataSet in it, if that matters. So judging by jGardner's response, since the object passed was not a RawImage, I'm not gonig to be able to access any fields in RawImage or Image?
Can someone just shoot me now so I don't ever have to think about inheritance again?
> DataSetList is being passed. DataSetList extends LLEIceObject. Image does
> NOT extend DataSetList. Therefore, must I cast DataSetList to LLEIceObject,
> then cast that to RawImage?
Casting can not perform magic. if . DataSetList extends LLEIceObject and
and as you wrote before:
DataSet extends LLEIceObject
Image extends Dataset
RawImage extends Image
There is no way any object can simultaneously be a DataSetList and a (Raw)Image.
Suggestion: given the name DataSetList , perhaps this object has a
list of DataSet objects and perhaps one of those DataSet objects also has type RawImage,
or you can recurively dig down again and eventually discover
that illusive RawImage. Check the API for DataSetList.
> Therefore, must I cast DataSetList to LLEIceObject,
> then cast that to RawImage?
I don't think you quite understand how polymorphism works. when you pass a DataSetList to that method, you are not changing it into an LLEIceObject, you are simply CALLING it an LLEIceObject. it is still a DataSetList at runtime. There are two times when you can cast an object to another type of object:
Consider class A and class B which extends class A.
1. At any time you may cast B to A, but by doing so, you don't actually affect anything about B. You are just changing what you want to call it. Instead of saying "I have a B," you are now saying, "I have an A," which is technically true. I can say "I have a pet monkey" OR "I have a pet mammal." Both are true, one is more generic than the other, even though the mammal is still a monkey in reality.
2. If you have an instance of B which you are currently calling an instance of class A, you may cast it to type B. By doing this, you may now call it B. It is like saying "I have a pet mammal. By the way, it is a monkey." This statement is true.
What you have with DataSetList is a class C, lets say Mouse again. You can say "I have a Mouse," which is true. You can say "I have a mammal," which is also true.
But by trying to cast C to A to B is like trying to say, "I have a pet mouse, which is a mammal. My pet mammal is actually a monkey."
That makes no sense.
> Can someone just shoot me now so I don't ever have to think about inheritance again?
This is the one place where inheritance *does* suck: when you have to
do an explicit cast. We try to avoid these, but we all have to do them sometimes.
I'm afraid you look like a blind man lost in a huge foggy maze.
The point is that beside all that inheritance stuff, you don't seem to know what the reportEvent method is supposed to do:
> This method will send me an image. There is apparently data about
> the image in the RawImage class, as it has some fields like
> bitsPerPixel, imageColorSpace, etc.
>
> I need to access the fields in RawImage; these should be populated
> somehow through aEvent (or so I'm told) when the data returns.
What about clearing that point first ?
> I'm afraid you look like a blind man lost in a huge
> foggy maze.
And how does a blind man know whether a maze is foggy? or huge for that matter, hmm?
> > I'm afraid you look like a blind man lost in a
> huge
> > foggy maze.
>
> And how does a blind man know whether a maze is
> foggy? or huge for that matter, hmm?
I've been told that blind people have some sort of enhanced senses that compensates blindness. So why not ?
> > I'm afraid you look like a blind man lost in a
> huge
> > foggy maze.
>
> And how does a blind man know whether a maze is
> foggy? or huge for that matter, hmm?
Because a huge foggy maze can never be admitted into a blind man's senses (visual), he can never know he is in such a predicament unless this knowledge is presented to him a priori (somebody tells him so).
> > > I'm afraid you look like a blind man lost in a
> > huge
> > > foggy maze.
> >
> > And how does a blind man know whether a maze is
> > foggy? or huge for that matter, hmm?
>
> I've been told that blind people have some sort of
> enhanced senses that compensates blindness. So why
> not ?
With what sense does one detect fog?
And another thing: why does your registration date have dot delimiters whilst everyone else has forward-slashes. What makes you so special, hmm?
> With what sense does one detect fog?
Uhm... the sense of hygrometry ?
> And another thing: why does your registration date
> have dot delimiters whilst everyone else has
> forward-slashes. What makes you so special, hmm?
Well, I don't like slashes, so I simply requested Sun to change them into dots. Nothing special actually.
> With what sense does one detect fog?
Smell and feel.
Those of us that are sighted seem to think that we sense fog with our sight, when in fact, it the lack there of that is the clue. Given that a blind person is already without sight, the scene is set for always being in a fog. The moisture and smell would be the next indicators, IMHO.
I think I've cracked the code! After this is over I'll feel like I can hack into the U.S. defense network. It turns out that DataSetList contains an array of DataSets. These DataSets are instances of RawImage, so I casted...well just look at the code.
if (aEvent instanceof DataSetList) {
DataSetList datasetlist = (DataSetList)aEvent;
System.out.println("You succeed.");
if (datasetlist.dataSets[0] instanceof RawImage) {
System.out.println("You succeed again.");
RawImage img = (RawImage)datasetlist.dataSets[0];
System.out.println("Colorspace: " + img.imageColorSpace);
System.out.println("bitsperPixel: " + img.bitsPerPixel);
} else {
System.out.println("Your hopes and dreams are crushed.");
}
} else {
System.out.println("You fail.");
}
Maybe for spite I'll change those System.out.printlns in the else statements to Exceptions that say "these are not the droids you're looking for" just in case the guy who designed all this inheritance ever has to maintain my code.
Message was edited by:
Djaunl
> > I'm afraid you look like a blind man lost in a
> huge
> > foggy maze.
>
> And how does a blind man know whether a maze is
> foggy? or huge for that matter, hmm?
Mother Superior is sat in the bath, when another nun comes in and says "there's a blind man here asking for you, Mother Superior". Thinking "Oh, a blind man? Well that's ok, he won't see anything" Mother Superior says "send him in, Sister".
So the nun disappears and a minute later, in comes the blind man and says "Hello big t!ts, where d'you want these blinds put then?"
> > With what sense does one detect fog?
>
> Smell and feel.
>
> Those of us that are sighted seem to think that we
> sense fog with our sight, when in fact, it the lack
> there of that is the clue. Given that a blind person
> is already without sight, the scene is set for always
> being in a fog. The moisture and smell would be the
> next indicators, IMHO.
And how would a blind differentiate this from being near a cool shower with Jessica Biel
> Maybe for spite I'll change those System.out.printlns
> in the else statements to Exceptions that say "these
> are not the droids you're looking for" just in case
> the guy who designed all this inheritance ever has to
> maintain my code.
<waves hand>
We can go about our business.........
> > > I'm afraid you look like a blind man lost in a
> > huge
> > > foggy maze.
> >
> > And how does a blind man know whether a maze is
> > foggy? or huge for that matter, hmm?
>
>
> Mother Superior is sat in the bath, when another nun
> comes in and says "there's a blind man here asking
> for you, Mother Superior". Thinking "Oh, a blind man?
> Well that's ok, he won't see anything" Mother
> Superior says "send him in, Sister".
>
> So the nun disappears and a minute later, in comes
> the blind man and says "Hello big t!ts, where d'you
> want these blinds put then?"
>
Hahahaha- "put them over your eyes you Philistine!"
> > Maybe for spite I'll change those
> System.out.printlns
> > in the else statements to Exceptions that say
> "these
> > are not the droids you're looking for" just in
> case
> > the guy who designed all this inheritance ever has
> to
> > maintain my code.
>
> <waves hand>
>
> We can go about our business.........
Well I could take georgemc's ideas literally and actually create a DatShitDontFitException (I still have that entire post saved in my email inbox. Classic stuff there).
Oh, thanks to everyone who replied for your help. If I didn't get an internal server error when I try to assign duke stars, I'd dish some out.
> > > With what sense does one detect fog?
> >
> > Smell and feel.
> >
> > Those of us that are sighted seem to think that we
> > sense fog with our sight, when in fact, it the
> lack
> > there of that is the clue. Given that a blind
> person
> > is already without sight, the scene is set for
> always
> > being in a fog. The moisture and smell would be
> the
> > next indicators, IMHO.
>
> And how would a blind differentiate this from being
> near a cool shower with Jessica Biel
Clearly he's blind, not deaf and suffering from ED.
> the blind man and says "Hello big t!ts, where d'you want these blinds put then?"
And are you also a fan of Finbar Saunders and his double-entendres?
http://en.wikipedia.org/wiki/Finbarr_Saunders
> > the blind man and says "Hello big t!ts, where d'you
> want these blinds put then?"
>
> And are you also a fan of Finbar Saunders and his
> double-entendres?
>
> http://en.wikipedia.org/wiki/Finbarr_Saunders
Ask Dave Minter about Finbarr Saunders - he's always fnerr'ing away
It took me about five minutes to get that joke. Seems this thread has degraded a bit. As long as filestream doesn't come in here posting about Indian food there's still a chance!
> It took me about five minutes to get that joke. Seems
> this thread has degraded a bit. As long as filestream
> doesn't come in here posting about Indian food
> there's still a chance!
He's like BeatleJuice, you have to say his name three times before he appears.
Message was edited by:
kevljo
> > It took me about five minutes to get that joke.
> Seems
> > this thread has degraded a bit. As long as
> filestream
> > doesn't come in here posting about Indian food
> > there's still a chance!
>
> He's like BeatleJuice, you have to say his name three
> times before he appears.
>
> Message was edited by:
> kevljo
BeatleJuice? Was there nothing the Fab 4 wouldn't merchandise?
Talking of merch' wh0res, Aerosmith do a novelty doormat that says "Walk this way" :-)
> > > It took me about five minutes to get that joke.
> > Seems
> > > this thread has degraded a bit. As long as
> > filestream
> > > doesn't come in here posting about Indian food
> > > there's still a chance!
> >
> > He's like BeatleJuice, you have to say his name
> three
> > times before he appears.
> >
> > Message was edited by:
> > kevljo
>
> BeatleJuice? Was there nothing the Fab 4
> wouldn't merchandise?
>
> Talking of merch' wh0res, Aerosmith do a novelty
> doormat that says "Walk this way" :-)
I meant Beetle Juice, and misspelled it the first and second time, which is par for the course. Now I must go. There is a wall with my head's name on it, and I am way behind schedule.