Say I have a struct: ```st = { top = { ...
# cfml-beginners
a
Say I have a struct:
Copy code
st = {
    top = {
        middle = {
            bottom = "value I want"
        }
    }
}
And a path to a key held in a string, eg:
Copy code
keyPath = "top.middle.bottom"
Is the CFML-idiomatic way of fetching the value I want gonna be something like:
Copy code
valueIWant = structGet("st.#keyPath#")
Repro: https://trycf.com/gist/ac86ec8b0166c0715e37ac1f74c87684/acf2021?theme=monokai Note: I know this works, I'm just wondering whetherin CFML-current there's a better way?
structGet
always seems so clunky to me. I feel I am forgetting something...
b
To be honest, this is where I use evaluate
I do this serveral places in CommandBox where commands like
Copy code
server set web.ssl.enable=true
translate to a struct behind the scenes
The only difference is I convert it to bracket notation
I also support things in my example like arrays which kept me away from any struct-specific functions.
a
Yeah I thought about using
evaluate
too. I'm less against it than most, but... it's code I'm using in a blog article and I don't wanna... distract ppl's focus.
b
I don't know of another way outside of eval and structGet outside of parsing the string as a dot-delimited list and crawling down the struct with bracket notation, but there's no benefit at all that approach. (well, I suppose it's safer than eval, but significantly more complicated than all the other options presented)
Right, if the input of the struct keys isn't trusted, you wouldn't want to go there
a
Bracket notation... you don't mean like
st[keyPath]
though right, cos that refers to a single key called
top.middle.bottom
, it's not resolved, yeah?
Yeah I'm always wondering if when using
evaluate
in shared code one MUST sanitise it, cos one dun't know what value it's gonna be receiving. Low risk, but... due diligence etc.
b
Exactly, so if you did
keyPath.toArray('.')
, then looped over it and did
currentPointer[nextKey]
to drill down. But think that's a lot of boilerplate
So long as all your key names will never have dots within the, I think structGet is your best bet
a
Copy code
public any function get(required string key) {
    lock scope="application" type="readonly" timeout=5 throwontimeout=true {
        if (isDefined("variables.applicationScope.#key#")) {
            return structGet("variables.applicationScope.#key#")
        }
        throw(type="ApplicationScopeProxy.KeyNotFoundException", message="Key [#key#] not found in application scope");
    }
}
It's literally that
It's not awful, I didn't like the
isDefined
, but... like
evaluate
... it's the tool for the job here I think
I actually woudl not mind
structGet
if it worked like
structGet(theStruct, thePath)
. I don't like how the struct is in the path too, for some reason.
b
isDefined() is typically faster if the value exists (and it doesn't need to go hunting) but since you're starting with a top level scope name, Lucee will optimize that pretty good
a
Also then
myStruct.get(path)
would work...
s
would be nice if struckeyexists()/mystruct.keyExists() could take a path like structget
a
Anyway... if y'all didn't shriek in horror @ that usage, I'm cool with it 😄
Cheers!
s
I would have shrieked if you wanted to actually use evaluate
a
heeheeeheee
s
I am right now going through a clients legacy code removing IIFs and Evalueates from all over the place
b
There's a time and a place for everything 🙂
a
^^ this in itself is a good lesson.
b
It's certainly used in the wrong place often times for sure
a
hahahahahaha. SO this is like balancing out its karma then, you reckon?
e
I commit tech heresy and just set a global variable with the application.websecURl =https://foo. As for "legacy" code, We (Yes, there is more than one of us) still have hard copies of the latest WAK, granted they are almost old enough to drive.
g
@Evil Ware I still both my WACK books. I also have a few from Jeff Peters, https://www.amazon.com/ColdFusion-XML-Objects-Jeff-Peters/dp/0975264753 https://www.amazon.com/ColdFusion-Lists-Arrays-Structures-3rd/dp/0990502805 I still use them on occasion.