Railo Tip: Magic Functions - Getters / Setters

I was digging around in the old Railo 2.0 documentation and I came across this little gem about magic functions (getters/setters). I thought I'd take a minute to update the documentation a little bit since things have changed as we can no longer rely on this scope since it is publicly accessible.

You can enable magic functions in the web / server context by going to http://{your host name}/railo-context/admin/web.cfm?action=resources.component (or, if you want it enabled server-wide, change that to server.cfm) as seen in the screenshot below:
Magic Getter/Setter setting

Once, you've checked and enabled it, we're ready to start with some code. I created person.cfc with the following code:


<cfcomponent>
<cffunction name="init" access="public" output="no" hint="initalization">
<cfreturn this>
</cffunction>
<cffunction name="setage" access="public" output="no" hint="This sets the age">
<cfargument name="value" required="yes" type="numeric">
<cfif arguments.value LT 30>
<cfthrow message="Blah! You're just a young pup!">
<cfelse>
<cfset variables.age = arguments.value>
</cfif>
</cffunction>
<cffunction name="getage" access="public" returntype="string" output="no" hint="This gets the age">
<cfreturn "My age is #variables.age#">
</cffunction>
<cffunction name="dump" access="public" output="no" hint="I'm just here for debugging purposes">
<cfreturn variables>
</cffunction>
</cfcomponent>

So, this is a person object, but I didn't declare age or name anywhere. I did create two age specific functions (getage / setage). Now, I'm going to call my Person component via my index.cfm:


<cfset oPerson = createObject('component','person').init()>
<!--- In Railo 3.1.2.015, you can write this as: <cfset oPerson = new person()> --->
<cfdump var="#oPerson#">

My dump:
My dump of the object

Now, let's play around a little bit by setting some properties and cfoutput'ing it:


<cfset oPerson.name = "Todd Rafferty">
<cfset oPerson.age = 37>
<cfoutput>#oPerson.name#</cfoutput><!--- Result: "Todd Rafferty" --->
<cfoutput>#oPerson.age#</cfoutput><!--- Result: Guess? Check below to find out if you're right! --->

The result:
Result
So, you can see here that oPerson.age didn't output to just "37", it actually returned "My age is 37" as found in the getage() function. Now, what happens if I try to lie and I say that I'm 29?

<cfset oPerson.age = 29>

The result?
Error!

:(

As noted in the old documentation, you could further expand on this so that setName() validates that the user actually exists and throws an error if it doesn't. If you're running Railo 3.x at the moment, you have full access to this as it has been there since Railo 2.0!

Update (July 27th) - This is now available on the Wiki

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Tony Nelson's Gravatar Very cool! I've been wanting to have something like this for awhile, but had to resort to using onMissingMethod to handle the logic. So instead of #oPerson.age# I'd have #oPerson.age()# and instead of <cfset oPerson.age = 37> I'd have <cfset oPerson.age(37) />. While it's not that big of a syntax change, your way is definitely more in line with true implicit getters and setters.
# Posted By Tony Nelson | 16.07.10 16:06
BlogCFC was created by Raymond Camden. This blog is running version 5.9.1.002. Contact Blog Owner