Anyone able to help me understand what is happenin...
# cfml-general
n
Anyone able to help me understand what is happening here? Are properties lazy-loaded? test.cfm:
Copy code
<cfscript>
	Dog = new Dog();
	test = Dog.doesItHavePaws();
</cfscript>
Dog.cfc:
Copy code
component accessors="true" extends="Pet" {
	function init() {
		super.init();
		return this;
	}

	boolean function doesItHavePaws() {
		var result = variables.hasPaws;
		writeOutput( "result: " & result );
		return result;
	}
}
Pet.cfc:
Copy code
component accessors="true" {
	property name="hasPaws" type="boolean" default="true";

	function init() {
		return this;
	}
}
The result is an error: Element hasPaws is undefined in Variables. However, if I add a writedump(Dog) in test.cfm, it shows the dump, and the function works fine, outputting my result.
Copy code
<cfscript>
	Dog = new Dog();
	writedump(Dog);
	test = Dog.doesItHavePaws();
</cfscript>
Alternatively, I can use getHasPaws() in the doesItHavePaws() method (instead of variables.hasPaws) and that works. From what I've read, though, variables is private to the CFC, but that's where I'm accessing it. And what would an external call to writedump() the object do that would make the default of the property suddenly work fine? Also, this seems to be related to the extended component's properties only. If I move the property into Dog(), variables.hasPaws works fine.
c
Which CF engine? Seems to work as expected on Lucee 5.4.6.9
n
ACF 2023
c
Maybe an ACF bug then? As long as it has a value at the time of calling, a property defined in a parent component should be available to a child.
c
Have you tried adding mappedSuperClass=“true” ?
n
No, just tried it, but no luck.
c
I always thought
mappedSuperClass
was just for ORM entity inheritance.
n
worth a try, anyway ¯\_(ツ)_/¯
I also tried
lazy="false"
on the property, but no luck.
That's orm too
b
I know lucee actually obeys default values on properties. Adobe didn't used to and I would have hoped they had changed that by now, but perhaps not
On an libraries that I needed to be compatible with all CFC engines, I always initialized my default values in the
init()
to be sure.
I can add here that BoxLang also obeys default values like Lucee does.
mappedsuperclass and lazy only apply to ORM entities, which these CFCs are not.
n
Seems not always. I've had mixed results.
"not always" meaning obeying default values
m
it seemed like to me on adobe that if I wanted the variables scope to reflect the default properly, I had to use the accessor first (getX() or setX()). I also usually just use the getter to access it, as it seems more consistently behaved. I'd either var result = getHasPaws() or var result = invoke("", "getHasPaws") if you want it easier to variabalize the hasPaws part.
👍 2
b
I think what you have found is a bug. This is confirmed by the fact that you don't get the error after inserting the writedump. You should report it, so Adobe can at least have a look at it. Here is why I think your original code should have worked. The line
property name="hasPaws" type="boolean" default="true";
implies that Pet.cfc implicitly contains the methods
getHasPaws()
and
setHasPaws(true)
, with
variables.hasPaws=true;
being implicitly defined in the setter.
I think what you have found is a bug. However what I consider a bug is the fact that you don't get the error after inserting the writedump. You should report it, so Adobe can at least have a look at it. I can think of a possible reason why your original code produces an error. The line
property name="hasPaws" type="boolean" default="true";
implies that Pet.cfc implicitly contains the methods
getHasPaws()
and
setHasPaws(true)
, with
variables.hasPaws=true;
being implicitly defined in the setter. The getter and setter are of course inherited by Dog. However,
variables.hasPaws
is a private variable in Pet.cfc. As such, it cannot be inherited by Dog, and so is distinct from the
variables.hasPaws
in Dog.cfc.
A test: add this method to Pet.cfc
struct function getVariables(){
return variables;
}
Then run the following on the test page:
<cfscript>
myPet = new Pet();
myDog = new Dog();
writedump(var="#myPet.getVariables()#", label="myPet.getVariables()");
writedump(var="#myDog.getVariables()#", label="myDog.getVariables()");
</cfscript>
You will see that
variables.hasPaws
is defined in myPet, but not in myDog.
👍 1