Recently I talked about conforming to using init() methods in my components. I had planned to use createObject().init() to make the call in one nice quick line.
There's just one problem, createObject() won't work for me in my preferred site structuring.
I like to house all my application-level and session-level variables in separate include files in an includes/ directory beneath the web root. In Application.cfc, I call to those files in onApplicationStart() and onSessionStart(). It's a nice way for me to compartmentalize code and keep Application.cfc from getting too messy. I've done this for years now in dozens of sites.
I keep all my components in a components directory on the same level as the includes directory. I initialize the components in the application scope because they change so little (only when a code release is done) that it makes sense to keep them there to limit overhead by only creating the object one time.
Until recently I would use CFOBJECT to create the component variable. I would call it like this:
Never a problem. I try to change it to:
and it blows up with the error "Could not find the ColdFusion component or interface components.myComponent".
For an hour I could not figure out why until digging enough showed me one huge difference between createObject() and CFOBJECT. While CFOBJECT is smart enough to know that the dot notation of the directory structure begins at the site root, createObject() only looks from the location of the template the call resides in. In this case it's the includes directory.
For kicks I added the createObject() call directly into the onApplicationStart() function in Application.cfc. It worked fine, confirming my lesson of the night that it has no capability to traverse up a directory structure, only down.
So it looks like I'll be sticking with CFOBJECT after all, at least until Adobe decides to give createObject() a little more flexibility. What stinks is that I'll have to make separate calls to the init() functions to get them run. Kinda defeats the purpose of them a little bit I think.
#1 by Don Q on 6/30/11 - 3:06 AM
THIS.Mappings[ "/componentsl" ] = ExpandPath('./components/');
Or whatever the actual path to the mappings are
#2 by daddy-o on 6/30/11 - 3:34 AM
Post back if that gets called automatically when the cfobject tag is processed. I'm curious.
#3 by Justin Scott on 6/30/11 - 3:41 AM
#4 by Andrew Scott on 6/30/11 - 6:41 AM
As for the createObject() I have been using this for almost 10 years now, and is much easier to use than the counterpart cfobject. But it certainly does traverse up without any issues what so ever.
So there must be another problem that is hindering this, the crerateObject function actually does check the local directory first to try to find what to load. However that is also provided that there is no components directory in your includes directory.
Because if there is then it will error as expected, however if there is not then it will go to the root of the application and try to traverse from there.
But to iterate this once more, what version of ColdFusion are you trying to run this on?
#5 by Rob Barthle on 6/30/11 - 2:07 PM
I am on CF 9.01 on OS X for my development server. My production servers are CF 9.01 on Linux.
@Andrew I am finding it to be the case that the init() method is NOT run without explicitly calling the method. I am using CFOBJECT at this time, have not tested that with createObject().
I wil look at mappings to see how those can help. One question, can an application using Application.cfm use application mappings? I have a legacy app that I cannot change to App.cfc that has a similar structure to what I described before, and are having the same issues when trying to use createObject().
#6 by Andrew Scott on 6/30/11 - 2:13 PM
#7 by Rob Barthle on 6/30/11 - 2:13 PM
#8 by Rob Barthle on 6/30/11 - 2:25 PM
Also I am a little confused on your statement regarding init() being run without being called directly. I am finding that not to be the case, and I haven't run across any documentation stating that it's different in CF9 than it was before in that regards. Could you post some code or point to where that's documented? Because when I instantiate the component without calling the init() method in any way, the init() method is not run and the variables set inside it are not set.
#9 by Andrew Scott on 6/30/11 - 2:35 PM
createObject('component','somepath.component').init();
or you can do this
createObject('component','somepath.component');
Both will run the init() method on the component, or you could do this.
component initmethod="constructor" {
public function constructor() {
}
}
#10 by Rob Barthle on 6/30/11 - 2:44 PM
#11 by Henry Ho on 7/4/11 - 7:17 PM
"Note: Only the new operator automatically invokes the initmethod or init function. The new operator returns the value returned by init or initmethod and if the return is void it returns the instance of the CFC. The cfobject tags and the CreateObject function do not invoke the function and you must explicitly call any custom initialization code."
http://help.adobe.com/en_US/ColdFusion/9.0/Develop...