Yincognito wrote: ↑October 10th, 2023, 4:59 am
Even more so, it only happens when using the
nested syntax for the variable when referencing it, it won't happen when using the classic syntax. I believe it's these two that cause Rainmneter to crash (well, technically, it hangs, but anyway)
I partially decided to use Nested Variables because they are dynamically resolved when they are used, I didn't wanna use Classic Variables because I didn't wanna add DV to the meter too (since I knew that previous function Nested Variables have), I actually didn't even test classic variables, but I understand now why and why referencing with the variable existing in the
[Variables] section dosen't do it
Yincognito wrote: ↑October 10th, 2023, 4:59 am
and the error appearing in the log before the hang seems to agree
Haha whoops, I didn't even check that window at all, I only checked the Skins tab to see the number go up and crash, never crossed my mind to go one page behind
Brian wrote: ↑October 10th, 2023, 7:01 am
What happens is
[#Minutes] is replaced with
([#Minutes] + 1), then it evaluated again and again until the internal stack is too large and Rainmeter crashes.
This self-referencing is the second (unintended, obviously) mistake.
However.....
This all shouldn't hang or crash Rainmeter...and fixing it is somewhat tricky. Either we can't allow a variable to self-reference itself (with nested syntax) within the variable's value, or we may have to limit how many nested substitutions can be done on a variable before it bails out and just returns with what it has. Obviously either way needs to produce an error message.
I'll have to chew on this for bit, so stay tuned...
-Brian
Sorry for the long text ahead.
I'll have to be honest with this one, but this seems like an intended behavior, Rainmeter is actually doing the correct job self referencing even if it means the app crashes.
To give an example where we can extract the same behavior, in LUA the
_G environment and
__index metamethod are self referential, when you do
for key, value in pairs(_G) do print(key) end and it references
_G back, that is indeed correct and dose the job right. If after that you try to get what each key's references (so for
string you try to get that it has
string.sub etc.), you'll run into infinity, recursively getting where
_G points (to itself).
So Rainmeter is doing the right thing, the question is if to limit the behavior to circumvent the crash in cases like this (I think Formula and Conditional Operations accept only 100 nested conditions, maybe for this behavior 3 nested is enough? but then again in other programming languages there are no rules for this, they just hang... and then crash) or to not do anything.
I personally wouldn't change anything, as the blame falls on the user for this/my error for initializing a self-referential behavior. I feel like this kind of behavior can't happen by accident (well, maybe it can if do
[#Minute[#Second]] but
[#Second] fails, I'd be hard pressed to find a user that could do this though) and is done only deliberately by hand.
I changed the post title to reflect the problem a bit better.
That's my rant over, as a funny little ending node, if you recursively try to get
_G's values you will end up with stuff like
_G._G._G._G.Measure.__index.__index.__index.__index.GetValueRange, which I find funny. For some reason
getfenv(1) is also in the global list and you have
1.SELF there.
LUA Code here for the thing I wrote to get that long string.