Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at Scotch On The Rocks (SOTR) 2011 (Edinburgh) with: Kev McCabe

ColdFusion 9's Implicit Getters And Setters Are Hard Coded

By Ben Nadel on
Tags: ColdFusion

The other day, I was day dreaming about the awesomeness that is ColdFusion 9 when I had a thought about its new implicit getters and setters. I know that ColdFusion 9 added the function, getFunctionCalledName(); so, I wondered if the implicit getter and setter methods were actually shared functions that operated based on their run-time handles. To test this, I set up a very simple ColdFusion component that had two properties:

Girl.cfc

  • <cfcomponent
  • output="false"
  • accessors="true"
  • hint="I am a test component with implicit getters.">
  •  
  •  
  • <!--- Define properties. --->
  •  
  • <!--- This will have both accessors. --->
  • <cfproperty
  • name="name"
  • type="string"
  • />
  •  
  • <!--- This will have only a setter. --->
  • <cfproperty
  • name="petName"
  • type="string"
  • getter="false"
  • />
  •  
  •  
  • <!---
  • Set some default values using the implicit setters
  • defined by the above CFProperty tags.
  • --->
  • <cfset this.setName( "Tricia" ) />
  • <cfset this.setPetName( "Cutie" ) />
  •  
  • </cfcomponent>

Notice that both properties of this Girl - name and petName - have implicit setter methods; but, only the name property has a getter. This will cause the petName property of this object to be unreadable. So the question is, if I copy the getName() function reference into the "getPetName" component key, will I be able to access the underlying property?

  • <!--- Create an instance of the girl object. --->
  • <cfset girl = new Girl() />
  •  
  • <!---
  • Copy the getName() reference into the getPetName
  • key - remember, there was no implicit getter for
  • pet name.
  • --->
  • <cfset girl.getPetName = girl.getName />
  •  
  • <!--- Output the various values. --->
  • <cfoutput>
  •  
  • Name: #girl.getName()#<br />
  •  
  • <br />
  •  
  • Pet Name: #girl.getPetName()#
  •  
  • </cfoutput>

As you can see, all we are doing is copying the getName() reference to another key within the same component. If the accessors work off of their run-time names, then this would provide access to the petName property which was not given an implicit getter by default. When we run this code, however, we get the following page output:

Name: Tricia

Pet Name: Tricia

As you can see, copying the implicit getter to another run-time variable did not change its underlying execution. As such, we can be confident that the code behind ColdFusion 9's implicit (or rather synthesized) accessors is hard-coded and specific to the originating property.




Reader Comments

Great stuff. I had a hard time with something similar in CF8. I was writing my own getters and setters, but had some problems figuring out a proper variable scope, because cfproperty had some issues with exactly this type of code.

Reply to this Comment

This is exactly what I anticipated would happen. I assume that the function pointer is overwritten and now they both point to the same method.

If this would have worked, it would have been a huge security gap in ColdFusion.

Reply to this Comment

@Steven,

It would have been a security gap; however, ColdFusion is so dynamic, that you can always plug in your own functions to existing CFCs at runtime to circumvent access rights.

So, what must be happening is that when the code is parsed, ColdFusion must actually read the CFProperty tags (which must be first in the file) and then compile individual getters / setter functions for each appropriate property.

I guess it makes sense; I just figured that this is the kind of thing that getFunctionCalledName() would be used for - otherwise, I have no idea for what core reason they added that method.

Reply to this Comment

Ben, you're a nut -- always digging deep into parts of CF that nobody in their right mind should ever use.

And that's why I *love* following your blog. Keep up the obsessively thorough work!

Reply to this Comment

@Ben,

Thanks my man. I just really like to know how this stuff works - to see how it can be leveraged for fun and profit (to borrow a phrase from Dan Wilson).

Reply to this Comment

Does anyone know if implicit getter and setter function are created as public or remote functions; can it be overridden?

Reply to this Comment

@Gio,

As far as I know, they are created as public; defaulting them to Remote would probably pose a security risk. Also, you can override them simply by defining your own. When ColdFusion builds the CFC, it will check to see if you have defined your own getter/setter methods before trying to synthesize them.

Reply to this Comment

What I am wondering is why are they faster than the regular explicit function or at least they seem to be in the few test we've done.

Reply to this Comment

@JF, Since the classes they belong to are generated only once, I assume it will be directly compiled into a java class. And then it would make sense that it's faster in execution, because the interpreter for CFML is just skipped.

But then again, I'm just making an educated guess here. Maybe someone with more thorough knowledge of CF's inner workings can prove me wrong...

Reply to this Comment

@JF, @Steven,

Hmm, interesting question. I had assumed that a synthesized getter/setter actually got compiled down into the same code as any manually coded UDF; but, like @Steven, that's just a guess.

What would be an interesting experiment was to see if the method could be removed from the CFC instance with a structDelete( cfc, "getterName" ). If that works, I would assume that the method is being treated like any UDF, but I don't think I've tried this.... and to be fair, it really wouldn't prove anything one way or the other :D

At the end of the day, synthesized getters and setters are useful until they are not. I wouldn't worry too much about the actual performance.

Reply to this Comment

@JF, @Steven,

.... that said, Elliott Sprehn always preaches that you should *believe in the language*. That it will be able to do things more efficiently than anything you could do manually. So, in that mindset, it would make sense that the synthesized methods are *at least* as fast, if not faster than manually coded methods.

Reply to this Comment

Hi Ben,

Out of curiosity I tried deleting the implicit method with StructDelete (it worked). Tried to access it after the delete and it was still available and returned me the default value.

Did that as well :

<cfoutput>#obj.method#</cfoutput>

and here is the result

coldfusion.runtime.ImplicitGetter@47156c03

Seems like it is instantiated directly in the CF runtime (? I think)..

Reply to this Comment

@Fred,

Very interesting! Now my curiosity is piqued. I'll have to do some exploration. Thanks for doing some digging.

Reply to this Comment

Post A Comment

?
You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.