Monday, August 16, 2010

Thoughts on Property Getters/Setters in ColdFusion

In ColdFusion 9, you can have ColdFusion automatically generate getters and setters for your properties by adding @accessors true to the component metadata. For example, the following two code snippets are practically identical.


component {
public string function getFirstName() {
return variables.firstName;
}

public void function setFirstName(required string firstName) {
variables.firstName = arguments.firstName;
}
}



/**
* @accessors true
*/
component {
property firstName;
}


Nice. That's a lot less code. Now what happens if you have a business rule where you always need the first name to be capitalized. I know it's not the best real world example, but it's straightforward. Simple enough, just override the generated getter by defining your own getFirstName method.


/**
* @accessors true
*/
component {
property firstName;

public string function getFirstName() {
return ucase(variables.firstName);
}
}


Done. While that works and is the correct way of overriding the getter, it doesn't quite feel cohesive enough to me since the getter isn't visually tied directly to the property. I think it would be better if we were able to define the getters and setters as part of the property, similar to how other languages do it.


/**
* @accessors true
*/
component {

property firstName {
get: function() {
return ucase(variables.firstName);
}
}

}


Obviously this is just hypothetical syntax, but I think it reads a lot better.

7 comments:

  1. I love the idea. You should suggest it to the ColdFusion team.

    ReplyDelete
  2. I really don't like that at all. Properties and methods should stay separate and I just think the syntax for creating getters and setters inline like that is straight up ugly!

    Just my 2cents

    ReplyDelete
  3. @Dan,

    What exactly is a property, aside from a pair of getters and setters around a component attribute? In my example, the getter is more an attribute of the property, rather than a method on the component. It could still compile down to traditional getFirstName/setFirstName methods, rather than having to call user.firstName.get() or something like that.

    And for what it's worth, here's how it looks in C#: http://www.csharp-station.com/Tutorials/Lesson10.aspx. My syntax just has more of a JSON flavor to it.

    ReplyDelete
  4. That's similar to the way it was done in Delphi:

    property Pending: Integer read FPending write setPending;

    (The variable name preceded by "F" was convention for the private variable that held the data.)

    This declaration says to read the property directly from the internal variable, but write it using the "setPending" function.

    The beauty of this was that if you had a declaration like that shown above, and wrote:

    this.Pending := 0;

    What appears to be a direct variable assignment is actual a call to the "setPending" accessor behind the scenes. I always found that syntax a little cleaner than

    this.setPending(0);

    ReplyDelete
  5. @jlcox,

    Yeah I like how the direct variable assignment gets routed through the accessor. That's how it works in Groovy and in Railo too, using what they call "Magic Functions": http://www.railo.ch/blog/index.cfm/2010/7/16/Railo-Tip-Magic-Functions--Getters--Setters

    ReplyDelete
  6. I know I am late to the party, but I am absolutely on board with this idea. Very similar to .NET syntax:

    public class Person
    {
    public string Firstname { get; set; }
    public string Middlename { get; }
    public string Lastname { set; }
    public int Age {
    get{ /* do stuff */ }
    set{ /* do stuff */ }
    }
    }

    ReplyDelete