Search code examples
coldfusioncfmllucee

Unexpected behaviour with accessors=true on a component


I am trying to use synthesised accessors on a component on Lucee (although this issue seems to be the same on ColdFusion too).

Repro code:

// Person.cfc
component accessors=true {

    property firstName;
    property lastName;

    function init(firstName, lastName){
        variables.firstName = arguments.firstName;
        variables.lastName = arguments.lastName;
    }

}

And the calling code:

// person.cfm
person = new Person("Abigail", "Bowen");
writeDump(person);

Notice how I am not using the synthesised accessors here, I am purely setting the argument values into same-named variables-scoped variables.

However when I run this code, I see this:

Dump output showing properties

Note how the properties have been populated. There's no problem with this, but I'm clearly not understanding how the accessors flag is supposed to work. I thought it was merely intended to synthesise some accessor methods for me (which it has), but that's all.

Also note that if I modify the CFC definition to not set accessors to true, then the dump shows this:

Dump with no properties

So no synthesised accessors (as expected), but also now the properties aren't even being displayed (with the variables-scoped values or not).

I don't really understand this conflation of "properties" and the accessors setting? Surely the accessors setting should only impact whether those accessor methods get created?

If I was only seeing this on one of the platforms, I'd probably put it down to a vagary of how writeDump() interprets the property definitions. But the behaviour is the same on ColdFusion 11, so it really does seem like there's some difference in behaviour I'm not quite getting.

Can anyone explain this? Are there any docs which explain it? If not... um... why not?

My underlying concern here is that the property values are not being stored "properly" and might cause me problems once I implement more of the code.

UPDATE: At least on ColdFusion, it seems to be just a change in writeDump()'s behaviour, because if there are getters for the properties (whether or not the accessors flag is set) then the property values start showing up in the dump. This is not the case on Lucee though, so there's still a question mark there.

For the sake of full disclosure, this question is a summary of a question I also asked on my blog ("CFML: trying to understand accessors"). The duplication is intentional as my blog gets a different audience from that of this site.


Solution

  • Without accessors=true, the property declarations are just metadata.

    With accessors=true, the property declarations trigger the generation of getters / setters and thus a property is both a variables scope item and a pair of methods.

    In your constructor, you assign to the variables scope items -- which would be the same as using the generated setters -- and when CFML dumps the component, it sees the property metadata and the generated getters and so it displays the values those properties have (since it can easily and safely call the generated getters).