Expressions and LuaXP Functions
-
For example, I like to pre-format the messages I send via SMTP, and routinely define:
msgText := "Hello from Vera. \n\n I see you are running MSR! \n \n Sincerely, Vera"
-
Yes, will happen. It raises priority on another "to-do" item for the parser, which has rather "blunt" string lexing at the moment. I've got a more formal version working now, but I want to play with it a little more before I commit it to MSR.
-
You make it, I break it.
-
@toggledbits I can't seem to concoct a meaningful example of
DO
..DONE
, since I'm probably not grasping its intended function within the MSR framework.
Does it have a use here, and if so, how would such a statement look? Thanks! -
toggledbitswrote on Mar 25, 2021, 9:13 PM last edited by toggledbits Mar 25, 2021, 5:28 PM
do...done
is intended to help thefirst
andeach
statements (but can be used anywhere, really).- the
each
andfirst
statements operate only on a single expression; do...done
encapsulates multiple expressions (separated by comma), but looks like a single expression toeach
andfirst
;- The result of a
do...done
statement is the value of the last expression executed within it.
Here from my own configuration is an example:
each detector in leak_detectors: do d=getEntity(detector), d.attributes.arming.state && d.attributes.binary_sensor.state ? d.id : null done
There's a separate expression called
leak_detectors
that provides an array of leak detector entity IDs (canonical, across controllers, of course). Theeach
statement iterates over each of them. Thedo...done
encapsulates two expressions: the fetch of the entity stored to a local variable in the first, and then uses that local variable twice in the second expression. The result of thedo...done
is the result of the last expression, which is the detector's ID if it is armed and tripped, or null otherwise. With aneach
expression, anynull
s do not appear in the final array.The idea should be familiar from RFV, although the construction is a little different: it's a loop over a list of known leak detectors and builds an array of those that are armed and in alarm (if any, hopefully not).
- the
-
For a lark, I defined a test variable as:
testObj = { a:5, b:2, c:"cat"}, each num in values(testObj): r = isNaN(num) ? " That's all!" : "Libra owns " + num + " cats"
which spits out:
["Libra owns 5 cats","Libra owns 2 cats","Libra owns cat cats"]
while I had actually expected (due to the
NaN
:["Libra owns 5 cats","Libra owns 2 cats"," That's all!"]
Also, am noticing that the Expression 'value' windows always contract to their initial (1.25-line tall) height, rather than remember what the user enlarged them to.
Are both of these "expected behaviors" in MSR??
-
toggledbitswrote on Mar 25, 2021, 10:07 PM last edited by toggledbits Mar 25, 2021, 6:17 PM
The
isNaN()
is a yes... unlike JavaScript, the lexpjsisNaN()
literally tests to see if the argument isNaN
, which"cat"
is not. You'd need to write your test asr = isNaN( int( num ) ) ? ...etc.
I can't store your selected/custom field sizes. I haven't poked harder into getting it to auto-size. I've done that before, but for some reason it isn't working and I haven't bothered to track it down yet.
-
I'm back with another whopper. Variables allow multiple comma-separated statements, like:
b = 3, c = b + 2 // yields 5
but go bonkers when you try:
testArr = [1,2,3], testArr[1] = 5 // parsing error (similar result with Objects)
By design?
-
Yes, assignment to simple variables only; the left side of an assignment can only be an identifier (right now).
-
This one's got me stumped now:
testCalc
=each num in [4,5,6]: do [num, num+1, num+2] done
yields:
[[4,5,6],[4,5,6],[4,5,6]]
instead of:
[[4,5,6],[5,6,7],[6,7,8]]
Or have I stumbled again? (I do realize the DO..DONE is a red herring, but removing it doesn't change the result.)
-
Nope, that's clearly wrong. Not hard to fix. I found a spot where the executive was rewriting a variable rather than returning a copy, specific to arrays, so this particular test would hit it, any other data type would not. Good catch!
-
Already posted as a PR with much-simplified rendering of underlying formula.
-
OK. It may or may not make today's build. I'm still testing other parts of my parser changes.
-
Here's an odd response, to an expression defined (in 21085) as:
testStr = [ "cat", " dog", "idle ", " jump " ], trim(testStr)
// result = (string) "cat, dog,idle , jump"
// note (a) the lopsided leftover spaces, (b) concatenation into a single string, (c) type coercion into String
// unsure whethertrim()
ought even accept Array as input? -
Meanwhile, this expression is returning the original string when I actually use a Regex as the "split" term:
testStr = "Th3 sw1ft br0wn c4t!", split (testStr,"1",2)
// returns ["Th3 sw","ft br0wn c4t!"]
// expectedtestStr = "Th3 sw1ft br0wn c4t!", split (testStr,"\d",2)
// returns ["Th3 sw1ft br0wn c4t!"]
// unexpected -
Another to ponder:
testObj = {animal:"cat",planet:"earth",size:"big"}, k = keys(testObj), each key in k: v = testObj.key
produces an empty array
[]
rather than (the expected) ["cat","earth","big"]. (Won't parse at all using.[key]
btw.) -
The correct syntax here is
testObj[key]
Basically,
[]
and.
are nearly equivalent member accessors. In JavaScript and lexpjs you can, for example, usearray.0
to refer to the first element of an array, same asarray[0]
. The difference between them is that the interior of[]
can be an expression, where.
must only have an identifier on its right-hand side. So when youtestObj[key]
, it will use the value ofkey
for the member access. It would also be the case thattestObj.animal
andtestObj['animal']
are equivalent.Your earlier
split (testStr,"\d",2)
example doesn't work because"\d"
is parsed as escape plus d, which is simply the letterd
, which is not what you want. You want a literal backslash followed by ad
, which would be the string"\\d"
to get the RegExp character class for digits 0-9. This is also the way JavaScript would parse it and behave:> t="The quick brown f0x" 'The quick brown f0x' > t.match( "\d" ) null <---- No match! > t.match( "\\d" ) [ '0', index: 17, input: 'The quick brown f0x', groups: undefined ] >
-
Ah, typical of me not to have known the precise array['key'] syntax offhand.
Yay, that variant works as advertised. (You were supposed to be out having fun today!)
And thanks for the pro tip re: "slash"-escaping the right way.
I was thrown off by this one working as expected (even without the double slash construct):testStr = "Does this work?", match(testStr,"\st")
// yields " t"
-
Fun!? I'm Clonezilla-ing everyone's desktops, and retiring my old Linux server that has served as the main NAS, moving the Synology into that role. Lots of services to move (which has been done over time, but the last-minute cut-overs for some things that couldn't), etc. Busy busy!
The other example, "\s" is an unrecognized escape sequence so it's leaking it. I'll fix that. "\s" is what's required.
-
This post is deleted!
61/126