http://coldfusion.com logo
#lucee
Title
# lucee
d

David Rogers

03/04/2022, 10:04 PM
static initialization ordering, are there any guarantees?
Copy code
import Foo.Bar; // does this trigger a classload of Foo.Bar, or just fixup mappings
component {
    function init() {
        var x = Bar::staticProp; // guaranteed to be init'd?
    }
}
d

Daniel Mejia

03/04/2022, 10:05 PM
you can import that way?
d

David Rogers

03/04/2022, 10:06 PM
yeah but I don't know if it triggers a classload or just patches the mapping lookups
d

Daniel Mejia

03/04/2022, 10:07 PM
I understand your question now. You should try it
d

David Rogers

03/04/2022, 10:07 PM
oh it works, I don't know if it's guaranteed to always work though
d

Daniel Mejia

03/04/2022, 10:08 PM
oh
is this a lucee only feature?
d

David Rogers

03/04/2022, 10:08 PM
maybe so
d

Daniel Mejia

03/04/2022, 10:09 PM
so in your test, is it init'd?
d

David Rogers

03/04/2022, 10:09 PM
@zackster is "Bar::staticProp" guaranteed init'd IF there is a static initializer in Bar for
staticProp
?
yes it is initialized as expected, I want to know if there are any gotchas here though
a

Adam Cameron

03/04/2022, 10:18 PM
"what happened when you tried it" would be my first response
And if it works then you can say "yeah that thing I asked about works" or if not "oh this thing I expected to work didn't seem to work, here's the code, here's the error, here's what I expected, and here's how my expectations weren't met. So what's up with that?"
d

David Rogers

03/04/2022, 10:22 PM
yeah, the thing I asked about works, but I don't understand what happens when I say Bar::Baz.
I would like insight into the above if anyone has it available. Thanks!
a

Adam Cameron

03/04/2022, 10:24 PM
It'd be interesting to see what happens if you put a
writeOutput("did this run?")
in the static constructor. When would that appear? On the import? On the access of the static variable?
d

David Rogers

03/04/2022, 10:26 PM
yes, that's a good thing to look into, I'm just about that right now.
1
a

Adam Cameron

03/04/2022, 10:26 PM
As for
// guaranteed to be init'd?
... no it's absolutely not guaranteed to be inited. Static variables belong to the class, not an object instance of the class. One does not need an object instance of Foo to access Foo::bar
That's the whole thing about static properties.
(and BTW normally I would try code questions I ask, but I CBA cranking up a CFML server to test ATM, and trycf is no help for this sort of thing)
I would expect that the static constructor would be loaded when you first use the static operator on the class name (eg:
Foo::
)
And only once for the lifetime of the JVM. After that first load... it's done.
d

David Rogers

03/04/2022, 10:31 PM
yes, I would also expect uttering
Bar::
would trigger a classload of Bar.cfc, i don't see anything that promises that, so I'm being paranoid.
a

Adam Cameron

03/04/2022, 10:32 PM
Which is pretty reasonable in CFML situations, sure
I have only used static variables/methods minimally, but they have always behaved as I would expect
👍 1
However I have never needed to understand the timing of their existence; it's been sufficient that when I go
Foo::BAR
that I get an expected value.
Perhaps not an emphatic answer to your question, but you know what I'm like and if anything wasn't to my expectation I'd've made sure to whine about it.
d

David Rogers

03/04/2022, 10:41 PM
talking this out helped me figure out the simple sanity check: while the server is running, create a new CFC file, and access it somewhere exactly once and only in a static way yes, it triggers a classload
d

Daniel Mejia

03/04/2022, 10:44 PM
how do you access it only in a static way?
d

David Rogers

03/04/2022, 10:45 PM
only ever say
SomeComponent::someStaticProp
1
d

Daniel Mejia

03/04/2022, 10:45 PM
ah I see
a

Adam Cameron

03/04/2022, 10:46 PM
And just an import doesn't trigger it?
(I'd not expect it to)
d

Daniel Mejia

03/04/2022, 10:47 PM
From the lucee docs, I don't understand the second statement "if the component is loaded"
Copy code
// Example3.cfc
Component {
	//instance constructor body
	dump("this is executed every time a new instance is created");
	//static constructor body
	static {
		dump("this is executed only if the component is loaded for the first time");
	}
}
d

David Rogers

03/04/2022, 10:48 PM
if the jvm has the cf-generated class file loaded or not
1
a

Adam Cameron

03/04/2022, 10:49 PM
Good question. @David Rogers if you adjust your test to only create an instance of
SomeComponent
, but never access any of its static stuff, does its "class" still load?
(I would presume: "yes" again)
d

David Rogers

03/04/2022, 10:51 PM
yes, createObject and new trigger a classLoad (if it hasn't already been loaded)
2
a

Adam Cameron

03/04/2022, 10:52 PM
I like doing tests like these to get a better uderstanding of what's going on.
Nice work fella
🤘 1
d

Daniel Mejia

03/04/2022, 10:56 PM
Thanks I just learned something new. Now I would just like to know what the benefit is of using static constructs, and some use cases. If either of you have a minute to explain I would really appreciate it.
d

David Rogers

03/04/2022, 10:58 PM
if you got static data, pop it in a static block
d

Daniel Mejia

03/04/2022, 11:00 PM
I guess its that simple. access your static data without the need of creating instances of that class.
a

Adam Cameron

03/04/2022, 11:04 PM
d

David Rogers

03/04/2022, 11:07 PM
i think they pulled the
static {}
initializer block syntax from java
(in response to "...and I don't know why they chose
static { }
instead of
staticInit() {}
)
1
d

Daniel Mejia

03/04/2022, 11:30 PM
Adam good article
@David Rogers ACF 2021 now supports static constructs too
I found my answer
d

David Rogers

03/04/2022, 11:55 PM
i guess we pay for pathmap lookup everytime we say
Foo::
?
Copy code
import Foo;

sys = createObject("java", "java.lang.System");

function benchSlow() {
    var result = [];
    for (i = 0; i < 100; i++) {
        var start = sys.nanotime();
        var v = Foo::someProp;
        var end = sys.nanotime();
        result.append(end - start)
    }
    writedump((result.avg() / 1e6) & "ms"); // 0.0130ms
}

function bench2() {
    var result = [];
    var someProp = Foo::someProp;

    for (i = 0; i < 100; i++) {
        var start = sys.nanotime();
        var v = someProp;
        var end = sys.nanotime();
        result.append(end - start)
    }
    writedump((result.avg() / 1e6) & "ms"); // .0007ms
}
d

Daniel Mejia

03/05/2022, 12:24 AM
@Adam Cameron why do you use this syntax?
Copy code
static {
   static.CACHE_KEY = "BRICKONE"
}
is
static
scope inside the static block better or required?
a

Adam Cameron

03/05/2022, 7:24 PM
The pseudo-constructor is only run when objects are created, not when the class is loaded. So if you want static values to be set on the class without an instance of it ever being created, you need to have those assignments in the static initialisation block.
1
a

Andreas

03/06/2022, 9:50 AM
Just some additional video about static functions by micha

https://youtu.be/B5ILIAbXBzo

👍🏾 1
👏🏾 1
The code of the videos 👆
d

Daniel Mejia

03/08/2022, 2:36 AM
@Andreas I forgot to mention that the video is a really good explanation of how it works and how it can be used.
👍 1