G'day:
Well there's a sequence of words I never expected to write down.
I just ran across something that I was reasonably surprised by when I first saw it. But having looked at it some more, I'm not sure. So I thought I'd ask the 3-4 people who actually read this blog to offer their insight.
Consider this traditional example of polymorphism in play:
// Base.cfc
component {
function runMe(){
doThings()
}
function doThings(){
writeOutput("BaseApp doThings called")
}
}
// Sub.cfc
component extends=Base {
public function doThings(){
super.doThings()
writeOutput("SubApp doThings called")
}
}
// from StandardInheritanceTest.cfc
it("A subclass will override a base class method", () => {
o = new Sub()
o.runMe()
expect(o.stack).toBe([
"Base doThings called",
"Sub doThings called"
])
})
The test (which passes) confirms what we'd expect: when runMe calls doThings, Because it's being called on a Sub object, the reference to doThings is referring to Sub.doThings even though the call is in Base. Hopefully no surprises there.
But what about this example:
// Base.cfc
component {
this.stack = []
doThings()
function doThings(){
this.stack.append("Base doThings called")
}
}
// Sub.cfc
component extends=Base {
function doThings(){
super.doThings()
this.stack.append("Sub doThings called")
}
}
// from PseudoConstructorInheritanceTest.cfc
it("A subclass will override a base class method", () => {
o = new Sub()
expect(o.stack).toBe([
"Base doThings called",
"Sub doThings called"
])
})
The difference here is the call to doThings is not done by the test, it's done within the pseudo-constructor of the Base component.
And in this case the test fails:
Expected [[Base doThings called, Sub doThings called]] but received [[Base doThings called]]
It would seem the pseudo-constructor code of a base-class is not aware it's being called from a sub-class. This doesn't seem right to me?
I'm running this code on Lucee, but I ran equivalent code on ColdFusion and the results were the same (so I guess that's something). And given the behaviour is the same on both I'm thinking this is more me not understanding something, rather than a bug. What do you think?
BTW whilst testing this I found out I can get the behaviour I actually want with a slight tweak to Sub.cfc. I changed from this:
component extends=Base {
function doThings(){
super.doThings()
this.stack.append("Sub doThings called")
}
}
To this:
component extends=Base {
doThings()
function doThings(){
this.stack.append"Sub doThings called")
}
}
IE: I replicate the way doThings is called in Base.cfc: from the pseudo-constructor. Both calls are made. For my purposes this will work fine. But I still do find it curious.
Or am I being daft?
Righto.
--
Adam