CFLint
CFLint copied to clipboard
Checking MISSING_VAR in conditional
MISSING_VAR does not account for declaration being in a separate branch.
<cfif someCondition>
<cfset theVal = 1>
<cfelse>
<cfset theVal = 0>
</cfif>
In the above example, the rule only reports theVal
in the first branch. It should report the declaration in both branches.
Curious to know does CF hoist var statements?
Me too.
Very interesting. It does hoist the scoping of var
statements. It does not, however, hoist the scoping of variables declared using local
. Ever since the explicit local
scope was introduced in CF9, I have preferred that notation, but I did not realize this difference existed.
@KamasamaK, what does your discovery mean for this task?
@ryaneberly In general, it means that if var
is used for a variable anywhere within the function, including after the initialization or in a block that is not even executed, that the variable is local-scoped everywhere in the function and fine. However, if only using local.
then it has to be on the variable's first use taking into account different execution branches.
From my testing, it seems that the MISSING_VAR rule only checks the first occurrence of a variable assignment. To be technically correct, a variable is still local-scoped even if var
is used after the first occurrence. However, I don't think it is good practice to do so and would probably just leave the check as-is for that case.
It gets complicated when using local.
instead of var
. You would have to either change the check to only consider var
instead or you would have to check that local.
is used anywhere a variable could be initialized at runtime. The block below would be an example of a case where the variable is conditionally local-scoped, but it will pass CFLint's check for MISSING_VAR.
string function foo() {
local.randomBoolean = getRandomBoolean();
if (local.randomBoolean) {
local.bar = "Absolutely";
} else {
bar = "Nope";
}
return bar;
}
From my testing, it seems that this rule only checks the first occurrence of a variable assignment. To be technically correct, a variable is still local-scoped even if var is used after the first occurrence. However, I don't think it is good practice to do so and would probably just leave the check as-is for that case.
Oh really, it does hoist? So you can pretty much posthumous var-scope a variable? I wasn't aware of that at all.
I agree - it's not good practice to do that. So, CFLint should report on the first occurrence, but why shouldn't it report on both?
@TheRealAgentK Yep. See this example to demonstrate.
Can you clarify what you mean by "report on both"?
@KamasamaK , do you still stand by the opening statement. MISSING_VAR should be reported on both branches?
@ryaneberly As long as the rule recommends using var
instead of local.
then no, it should not be necessary to report on both from that initial example. However, the issue from this comment would still need to be addressed.
@KamasamaK . I agree. And I am a fan of (consistent) local scoping over the use of var.