Using Partial Component Paths As Argument Types In ColdFusion
When you define a User-Defined Function (UDF) in ColdFusion, both the argument types and the return type can reference a ColdFusion component path. In my code, I typically use any
for such types because I find that including a long component path makes the code overly verbose. It turns out, however, that you don't have to include the entire component path. ColdFusion will happily validate component-based types even if you only use a partial path. And, the flexibility of the type reconciliation depends on the extent of the path provided.
I only just learned about this ColdFusion behavior from Kai Koenig in the LinkedIn post about his RayGun ColdFusion library (Raygun4CFML). When looking through his CFML code, I noticed that his method arguments referred to pathless components. And, that the referenced components were in a different directory. Example:
component {
public RaygunClient function init(
required string apiKey,
RaygunContentFilter contentFilter,
string appVersion,
RaygunSettings settings
) {
// ....
}
}
In this method signature, both the RaygunContentFilter
and the RaygunSettings
arguments refer to other ColdFusion components that live elsewhere in his project. I just assumed that this would break; but, Kai assured me that this works. So, I wanted to try it for myself.
To test this, I created two different ColdFusion components called Pet.cfc
. One lives in a directory named cat
and one lives in a directory named dog
. In a test file above both of these directories, I defined a method that accepts an argument of type, Pet
, and returns a value of type, Pet
. I then tried to invoke this method for each kind of Pet.cfc
.
<cfscript>
// Call the inspect method with TWO DIFFERNT TYPES of Pet component. Note that both of
// these CFCs are "Pet.cfc"; but, they are at two different component paths.
inspectPet( new dog.Pet() );
inspectPet( new cat.Pet() );
// ------------------------------------------------------------------------------- //
// ------------------------------------------------------------------------------- //
/**
* I inspect the type of the given Pet.
*/
public Pet function inspectPet( required Pet pet ) {
writeDump([
type: pet.type,
pet: pet,
// Try to narrow down inspection.
isOfTypePet: isInstanceOf( pet, "Pet" ),
isOfTypeCat: isInstanceOf( pet, "cat.Pet" ),
isOfTypeDog: isInstanceOf( pet, "dog.Pet" )
]);
return pet;
}
</cfscript>
When we run this ColdFusion code, we get the following output:

As you can see, the inspectPet()
function was happy to accept both types of Pet.cfc
as long as the component satisficed the argument type. Meaning, if the argument type were changed from the generic Pet
to a more specific dog.Pet
, ColdFusion would start throwing an error when a component of type cat.Pet
was passed-in.
According to Kai's code, this behavior also works for the CFProperty
tag's type
attribute; but, I didn't test this for myself. Clearly it works (in his code).
I can't believe that I've been using ColdFusion components for like 20 years and only just realized that this is how the component path validation works. It's so strange how little gaps like this can persist in one's mental model for so long.
Want to use code from this post? Check out the license.
Reader Comments
Incidentally, this doesn't seem to work with the
CFParam
tag. Not the partial path stuff, but using CFC paths in aparam[type]
attribute in any way. I looked at the docs, and it doesn't mention anything about CFC paths, so this might be a place where anany
type is required for passing CFCs into a ColdFusion custom tag (for example).@Ben
And you closed a gap for me, learned that satificed is not a misspelling or a "Euro" version of satisfied:
Per the Google:
@Danilo,
Ha ha, that's actually first time I've ever used it in my own writing. I recently learned it while listening to an episode of the Freakanomics podcast 🙃
Post A Comment — ❤️ I'd Love To Hear From You! ❤️
Post a Comment →