Using implicit scoping within functions

Hi Everyone;

Is there any REAL difference between these two?

  1. if( structKeyExists(local, “item”) AND !isNull(item) ) {
  2. if( structKeyExists(local, “item”) AND !isNull(local.item) ) {

In our code at the moment we explicitly use; form / arguments / url scopes - but do not consistently declare the local scope.

I understand that NOT explicitly declaring the scope, means there is “searching” to be done for a “match”. But it is my understanding that the local scope is checked first - so it (to me) seems redundant to include the use of “local.xxx” - after it has been declared.

Is it just “personal taste” - or is there a “real” advantage to always using an explicit scope?
Obviously - ALWAYS using the scope removes any/all doubt about the variable’s scope.

As a self-fulfilling example - in C / JS / Haskell / etc - you JUST use the variable name after it’s declaration.

And (I use the term VERY loosely)
Is there a “standard” that we should enforce in our design documentation / formatting tools?

Thanks
Gavin.

Don’t know if this helps, but here is some advice from the Lucee devs:

This is the rule I generally try to follow:

“Scope everything, except the closest scope.”

But, you might get into trouble sometimes, like it happened to me once. See https://lucee.daemonite.io/t/why-explicitly-scoping-in-cfml-can-be-essential-to-avoid-errors/10205

So I’d rather scope everything.

1 Like

@Gavin_Baumanis Using the debugging Implicit variable Access option under the Admin–>Debugging settings, you can see which variables are being accessed implicitly from which templates in the debugging logs

implicit_accesss

2 Likes

My preference is to scope everything. The code might be a bit more verbose, but you get a clearer picture as to where each variable has come from which I find useful.

1 Like

2 Likes

Thanks everyone.
Really appreciate the help / thoughts.

@andreas

In the thread you linked you have the following code.
(which is what we currently do)

public struct function testFunc(
        string someArgumentVar required
    ){
        var result={};
        result["someFilename"] = arguments.someArgumentVar ;
        return result;
    }

Sorry - if my original post wasn’t clear enough;
But what I MEANT was;
Should it be This instead?

        var result={};
        local.result["someFilename"] = arguments.someArgumentVar ;
        return local.result;

Does it matter / Is there and “standard” / does it make a difference (under the hood; speed / right-“ness”) / etc… specifically inside a CFC, inside a function, is the “local.” a requirement after the declaration?

As always thanks to you (and everyone else too! :slight_smile: )
Gavin.

I’m not sure, cause I don’t have that super insights/understanding of the Lucee core. Maybe someone else can chime in. But as today I do it like this… I don’t use “var” at all anymore:

        local.result={};
        local.result["someFilename"] = arguments.someArgumentVar ;
        return local.result;

var and local. are the effectively the same thing, both populate the local scope

and then as it’s the closest scope, once it’s been defined, you don’t need the local prefix anymore within the function

or use localmode=true (or modern) and it’s automatically done

public struct function testFunc(
        string someArgumentVar required
    ) localmode=true {
        result={};
        result["someFilename"] = arguments.someArgumentVar ;
        return result;
    }
2 Likes

Local scope mode is also an option in Lucee Admin > Settings > Scopes applied to either Server or Web contexts or can be defined in Application.cfc:

this.localMode = "modern";

Ha, and of course within mere seconds of posting that, I returned to @bennadel’s site where I read his compelling argument to not apply that to the entire application. :stuck_out_tongue:

2 Likes