Getting A Struct Key In Its Native Key-Casing In ColdFusion
In ColdFusion, structs are case-insensitive. This is very much a feature of the language, not a bug. But, in some rare edge-cases, I want to validate that the struct key I'm using has the same key-casing that the struct itself is using. There's no native ColdFusion function for this endeavor; so, I created the user defined function, structGetKey()
.
My particular use-case is that I have a struct acting as my data store. The user can view a detail page for each struct entry using a URL-provided key. What I want is to make sure that my detail page is always rendering the struct key as it's defined on the struct, not as provided in the URL.
To be clear, ColdFusion itself doesn't care—this is purely an aesthetic constraint on my end.
My structGetKey()
function simply gets the array of keys using the native function, structKeyArray()
, loops over the original keys, and returns the internal representation for the first match that it finds.
To see this in action, I've defined a struct with a single key. Then, I attempt to get that key three times with three different key-casings. The intention is that all three calls return the same exact value:
<cfscript>
// Note that the original key is being defined with a mixture of upper and lower case
// characters. Since this key is being QUOTED, it will remember its casing in both
// Lucee CFML and Adobe ColdFusion.
features = {
"product-HOME-1234-sql-performance": true
};
writeDump([
// Defining case.
structGetKey( features, "product-HOME-1234-sql-performance" ),
// All lower-case.
structGetKey( features, "product-home-1234-sql-performance" ),
// All upper-case.
structGetKey( features, "PRODUCT-HOME-1234-SQL-PERFORMANCE" )
]);
// ------------------------------------------------------------------------------- //
// ------------------------------------------------------------------------------- //
// Since this key is NOT QUOTED, it will depend on the server settings. In this demo,
// only Lucee CFML is configured to always maintain key-casing. Adobe ColdFusion has
// no special settings being applied. As such, it will lose the defining key-casing.
features.DiscountPricing = false;
writeDump([
// Defining case.
structGetKey( features, "DiscountPricing" ),
// All lower-case.
structGetKey( features, "discountpricing" ),
// All upper-case.
structGetKey( features, "DISCOUNTPRICING" )
]);
// ------------------------------------------------------------------------------- //
// ------------------------------------------------------------------------------- //
/**
* I return the given key using the internal key-casing.
*/
public string function structGetKey(
required struct target,
required string key
) {
// The native structKeyArray() function will return the keys using their internal
// representation. If we can find a case-INSENSITIVE match, we can return the
// original key to get the internal key-casing.
for ( var originalKey in structKeyArray( target ) ) {
if ( originalKey == key ) {
return originalKey;
}
}
throw(
type = "MissingStructKey",
message = "Key [#key#] doesn't exist."
);
}
</cfscript>
When we run this ColdFusion code, we get the following output:
![Screenshot of several write-dump outputs showing that the struct key is the same in all three calls to structGetKey() regardless of what key-casing was passed-in.](https://bennadel-cdn.com/resources/uploads/2024/struct-get-key-udf-demo@2x.png)
As you can see, when we pass the following three keys into structGetKey()
:
product-HOME-1234-sql-performance
product-home-1234-sql-performance
PRODUCT-HOME-1234-SQL-PERFORMANCE
... we always get product-HOME-1234-sql-performance
, which is the key-casing that the struct is actually using to store the given key.
Again, ColdFusion doesn't actually care about the key-casing that you use when accessing structs. My need is an aesthetic constraint in my current application.
Aside: I have come across one context in which ColdFusion key-casing does matter; and that's when accessing MongoDB BSON documents in Lucee CFML. This is a byproduct of the fact that structs are broad data type that actually paper-over many different Map-like implementations.
Want to use code from this post? Check out the license.
Reader Comments
This is 100% something I would do too! LOL
I'm OCD about setting my struct keys like this
myStruct[' keyName']
because I can't stand ALL CAP key names in my dumps.@Chris, it's funny how stuff evolves over time. In the early days of ColdFusion, especially when it was more of a walled garden, the looseness of everything was so great. Strings, numbers, dates, upper case, lower case, it all just worked. But, the moment ColdFusion had to start regularly touching the outside world (whether through JSON or API calls or Cookies), suddenly all this loosey-goosey behavior became a bit of a liability. Thankfully, we've closed the gap on a lot of this stuff (
true
no longer renders asYES
when generating JSON). But, there's still some edge-cases that we find ourselves having to work around.That said, I still love me some CF!!!
@Ben Nadel, that's so true. CF is a ton more fun to write than JAVA for example because of it's looseness (in my opinion). I like strict rules, but only to a certain (reasonable) extent :)
Post A Comment — ❤️ I'd Love To Hear From You! ❤️
Post a Comment →