Regular Jo
Regular Jo

Reputation: 5510

Including Application's user-defined-functions into modules

My application for simplistic purposes has

The result is that each of the 10 modules is duplicating the entirety of functions.cfm into each module.

I've re-engineered, turning functions into a component (it's named application._, which is copied into variarables._ inside each module and calling the functions like _.myUDF() which should be calling application._ by reference rather than recreating every function in the file for every component.

This should be the faster and lightest way to do this, shouldn't it? Can anyone suggest enhancements to this style, or give reasons why include might be preferrable, beyond the need to recreate the component if I change add functions to the component functions.cfc?

Upvotes: 2

Views: 121

Answers (3)

Adrian J. Moreno
Adrian J. Moreno

Reputation: 14859

Your file functions.cfm was included in your CFC files, so you can then call functionA() within any of those CFCs.

If you convert to functions.cfc and inject that object into your other CFCs, then you'll have to reference the functions objects within your other CFC files:

<cfset functions.functionA()>

So that's a lot of code to refactor.

Seems like you should extend your existing CFCs with functions.cfc:

<cfcomponent extends="cfc.functions">

This makes your other components child objects of functions.cfc, which therefore inherit the contents of functions.cfc. Now, from within any child CFC, you can call functionA() as you had when you included functions.cfm.

If that's more in line with what you want and you want ALL of your CFCs to include these functions, you can pull a totally baller move and update your CF server's core component.cfc from which all CFCs are extended. This file should be found in <CF_ROOT>\WEB-INF\cftags. I've done this in the past to add additional "native" functions to ColdBox applicaitons. Just make sure you track those changes in source control.

Upvotes: 4

Alex
Alex

Reputation: 7833

If I understood correctly, you already moved all your functions from functions.cfm to a component called functions.cfc? So your functions.cfc looks like this:

component {

    function doSomething()    { ... }
    function doAnotherThing() { ... }
    ...

}

Now let's go to the place where you initialize the components:

// create an instance of your "functions" component.
helperFunctions          = new functions();

// pass this instance to the others components using the constructor
// (components are passed by reference, so make sure your "functions" component is stateless)
application.o.items      = new cfcs.items(helperFunctions);
application.o.categories = new cfcs.categories(helperFunctions);

And this is how your items.cfc and categories.cfc should look like:

component {

    function init(functionsInstance) {

        // keep the reference to the "functions" component
        variables._ = arguments.functionsInstance;
    }

    function someFunction() {

        // use the passed "functions" component's functions
        variables._.doSomething();
        variables._.doAnotherThing();
    }

    ...

}

Now if you change something in your components, you simply have to run the "initialize routine" again. This will update/override the components stored in the application.o struct. So put these lines in a separate file to be included on application start and in the "restart" template you call whenever you need a live update.

Upvotes: 2

Matthew Moore
Matthew Moore

Reputation: 866

Using the include method should (as I understand it) allow you to make on the fly updates to the files, and have them reflect instantly without restarting the application. While storing them as an object in the application scope, would require restarting the application to refresh them. But is it important to have this ability? It's generally bad practice to be frequently altering the code in a production environment.

Loading functions.cfm into a variable would place it in memory, which means it would be present as long as the application is running. It would use more long term resources, but it would also make them quicker to access. While using include would use less resources long term, but it would have to load up functions.cfm every time one of the calling CFCs call it; making it slower, and potentially eating more short term resources.

The "best" choice would depend more on which feature is more important to your setting.

I am also curious why you transfer the application.functions to variables.functions. As long as the methods inside of functions.cfm don't write into the application scope - which should be locked at the method's local level - you should be able to simply reference them in the application scope.

Upvotes: 1

Related Questions