Is it possible to initialise the LOCAL scope like ...
# lucee
c
Is it possible to initialise the LOCAL scope like this:
Copy code
function foo(){
            
  var local = {};
  
  local = {
    strReturn = {
      criteria = {} 
    },
    strCompetenceTemplate = β€œβ€,
    aCriteria = [],
    iGlobalCnt = 0,
    lSelected = ""
  };
  WriteDump(var=local.strReturn);
}
When I try this, I get an error saying that the local scope is empty.
s
local
is a built-in scope.
var local
would ... create
local.local
no? what are you trying to do here that you can't just do
var someStruct = { myStuff };
and dump
someStruct
?
πŸ‘ 1
c
Even when you don't explicitly define the local scope, it does not work:
Copy code
function foo(){
  
  local = {
    strReturn = {
      criteria = {} 
    },
    strCompetenceTemplate = "",
    aCriteria = [],
    iGlobalCnt = 0,
    lSelected = ""
  };
  WriteDump(var=local.strReturn);
}
This throws an error, saying that the local scope is empty. Essentially, why do you have to do this:
Copy code
function foo(){
  
  local.strReturn = {
    criteria = {}
  };
  local.strCompetenceTemplate  = "";
  local.aCriteria = "";
  local.iGlobalCnt = 0;
  local.lSelected = "";

  WriteDump(var=local.strReturn);
}
This does not throw an error
s
Yes. Because in the first block you are defining
variables.local
or
local.local
You can't explicitly declare the local scope, as far as I know
local.strReturn
would be
var strReturn = { stuff }
inside the method
c
By the way:
Copy code
var local = {};
Does not create:
Copy code
local.local
Copy code
var local = {};
Implicitly initialises the LOCAL scope. It is used for backward compatibility to ACF9
s
πŸ€·πŸ»β€β™‚οΈ none of which addresses why you are doing any of this in the first place
c
This works as well:
Copy code
function foo(){
  
  var local = {};
  local.strReturn = {
    criteria = {}
  };
  local.strCompetenceTemplate  = "";
  local.aCriteria = "";
  local.iGlobalCnt = 0;
  local.lSelected = "";

  WriteDump(var=local.strReturn);
}
s
you can get rid of
var local = {}
in that block
c
Yes of course
s
tbh I haven't seen explicit local definitions in CF in probably seven or eight years
I can't think of any reason why you would explicitly reference
local
c
But I am trying to explain that adding it, doesn't prevent the code from working, because of your
local.local
theory
s
Yeah I would have assumed
var local = {}
would create
local.local
but I haven't used ACF in forever. I'm not surprised it has special significance for backwards compatibility, a lot of ACF behavior does
but ... why not just don't add it
c
You mean explicitly initialise
local
, rather than explicitly reference
local
It is used for backward compatibility to ACF9
The implicit LOCAL scope did not arrive until ACF10
s
I haven't seen either one in forever
c
Maybe not. But I am answering your question.
But this isn't what I am trying to ascertain?
Why can we not initialise all the
local
scope variables in a single struct
s
It sounds like what you are actually trying to do is 'declare a bunch of structs in local all in one go'
c
Yes. I am trying to declare a bunch of local variables, by declaring then in a struct
But Lucee throws an exception. ACF does not.
s
To the extent that
foo()
in this example has a bunch of baked-in defaults, I think the reason you don't see this very often is one of: 1. Is
foo()
better off as a component with a constructor, given that it has significant state elements 2. Is
foo()
better off as a method with arguments and defaults, if any of the items being declared ever change; 3. Is
foo()
better off referencing static variables in the parent component, if indeed those things don't change, since they would appear to be statically defined values 4. If none of the above are true and all the contents of
local
are just 'things this method is operating on or returning' then I would just write it as
var stuffRelevantToFoo = {}
because the explicit references to
local
are way messier in terms of readability than just defining one struct in local which will still let you use your (very slightly shorter-hand) 'declare a bunch of variables' approach
c
That's doesn't really answer why ACF excepts this kind of syntax and Lucee does not. Maybe, @zackster knows?
s
You could file a ticket for compatibility, they do take those differences seriously. But I wouldn't be surprised if they didn't want to do this one
πŸ‘ 1
z
we won't be changing this, it makes no sense
c
That's why I was interested to know from one of the guys who built/updates Lucee, the reasoning behind this syntax change. I mean, have you ever seen this:
Copy code
URL = {
  foo: "bar",
  bar: "foo"
}
OR
Copy code
APPLICATION = {
  foo: "bar",
  bar: "foo"
}
I am not sure I have? Maybe you cannot reassign or redeclare an in-built scope? But you can add props to them, like
const
in JS For instance in Javascript:
Copy code
// In JS you can do this
                          
const foo1 = {};
foo1.bar = "hello";
                          
console.log("foo1: ", foo1);
                          
// but you cannot do this
                          
const foo2 = {};
foo2 = {
    bar: "hello"
};
                          
console.log("foo2: ", foo2);
So, I would say that ACF is in the wrong here, for allowing this syntax...
s
ACF is wrong in plenty of ways they keep wrong for backwards compatibility. They have a lot more money tied directly to not breaking ancient ACF apps than the Lucee devs do. πŸ™‚
but yeah, I'd agree with that assessment
πŸ‘ 1
z
the thing is built in scopes are pre-compiled differently than normal variables
πŸ‘ 1
m
Copy code
function foo(){
  
  structAppend(local, {
    strReturn = {
      criteria = {} 
    },
    strCompetenceTemplate = "",
    aCriteria = [],
    iGlobalCnt = 0,
    lSelected = ""
  });
  
  WriteDump(var=local.strReturn);
}
πŸ‘ 1
s
that works but it's pretty fugly
βœ… 1
bringing one back around to 'but why'
πŸ’― 1
c
I give that a πŸ‘πŸ» for inventiveness 🀩
m
it is awful, but works on cf and lucee, and meets what he asked. i personally add the different keys separately, because readability feels better to me.
πŸ‘ 2
πŸ‘πŸ» 1
c
Yes. I always add the keys separately, but one of our ACF guys wrote this into a Lucee task and I was doing the code review. I told him that he would have to change the syntax. It’s clear he hadn’t tested it πŸ€”
b
I'm fairly certain the backwards compat code that Lucee has always ignore the value being set when var'ing a variable named
local
. You can't override an entire scope anyway since scopes are more than a struct. It was one of those things were 99% of the code just had
Copy code
var local = {};
so that was the one and only scenario that was allowed for. Basically, here is what happens β€’
var local = ANYTHING
will simple be ignored. β€’
local = anything
creates
varaibles.local
It's been a hot minute since these decisions were made, but I think they were either in the Railo ticket tracker (now gone) or perhaps the Railo Google groupe (archived somewhere)
πŸ‘ 1
c
Thanks for the insight @bdw429s
I get what you are saying about:
Copy code
var local = {};
Does nothing useful. But I wasn’t aware that the LOCAL scope was shorthand for:
Copy code
variables.local
Are you saying that:
Copy code
variables.local
Is an inbuilt scope? I know:
Copy code
variables
Is an inbuilt scope. But how can:
Copy code
variables.local
Be an inbuilt scope? I must say I thought LOCAL was an inbuilt scope like URL, FORM, SESSION etc. Therefore it cannot be redeclared or reassigned, but it can be mutated by adding props. Hence:
Copy code
local = {
    strReturn = {
      criteria = {} 
    },
    strCompetenceTemplate = "",
    aCriteria = [],
    iGlobalCnt = 0,
    lSelected = ""
  };
Does not work, because this is a redeclaration. I am now wondering why ACF allowed such syntax?
b
Are you saying that:
Copy code
variables.local
Is an inbuilt scope?
What? Huh? No no, no, no.
variables.anythingHere
is what you get when you run
Copy code
anythingHere = ...
And if
anythingHere
happens to actually be the word
local
, then you get (most likely on accident)
variables.local
which is in no way shape or form any sort of "proper" scope. It's simply a key in the
variables
scope called
anythingHere
, or in this case
local
.
πŸ‘ 1
I must say I thought LOCAL was an inbuilt scope
It is.
πŸ‘ 1
I am now wondering why ACF allowed such syntax?
ACF was always more lax with their scopes. I remember Micha talking about this years ago and how Railo was more protective, not allowing you to set anything into a base scope directly, but only into a key of said scope. The short answer to your question is likely, "Oversight, and lack of forethought/testing" but I assume it went back to the very early days of CF.
πŸ™ 1
c
Thanks for clearing this up. πŸ‘πŸ»
z
remember the days or every function have
var local ={};
and you could only have vars at the start of the function, ah the good old days
πŸ™ 1
c
Yes. I always wondered when that
var
rule changed? I remember when I was going to reprimand a Dev, for declaring a
var
half way through the function. And when I tested the code, to my surprise, it worked 🀩