We have moved at community.getvera.com

Author Topic: Is RETURN essential at end of scene script?  (Read 444 times)

Offline UKsub

  • Jr. Member
  • **
  • Posts: 51
  • Karma: +0/-1
Is RETURN essential at end of scene script?
« on: January 12, 2019, 07:23:59 pm »
Ever since i?ve had my veralite, over 6 years now on UI5, i?ve not included *return* at the end of my lua script unless i want it to act on a device, ie check some conditions this then return true/false to enable/disable/ignore device X,Y,Z, etc.

Some of my code does not trigger devices, perhaps just executing script and completing its task completely within the lua.
Should i still put *return* at the end of the lua script even if no further action is required?
It seems to have run fine for all these years but maybe this acounts for very occasional errors or perhaps its just good programming practice? (Maybe the system allows for this?)

Can anyone confirm please

Offline rigpapa

  • Beta Testers
  • Hero Member
  • *****
  • Posts: 1121
  • Karma: +187/-3
Re: Is RETURN essential at end of scene script?
« Reply #1 on: January 12, 2019, 08:24:23 pm »
Ever since i?ve had my veralite, over 6 years now on UI5, i?ve not included *return* at the end of my lua script unless i want it to act on a device, ie check some conditions this then return true/false to enable/disable/ignore device X,Y,Z, etc.

Some of my code does not trigger devices, perhaps just executing script and completing its task completely within the lua.
Should i still put *return* at the end of the lua script even if no further action is required?
It seems to have run fine for all these years but maybe this acounts for very occasional errors or perhaps its just good programming practice? (Maybe the system allows for this?)

Can anyone confirm please

In theory, with only Lua in the scene and no actions, there's no problem it could cause. In practice, you are at the mercy of Vera's implementation, which is unseeable and therefore unverifiable.

It will not cause problems, and likely avoid them, to always return true or false from scene Lua. I've seen things go wrong in this context without a return value, but I've never seen code with a boolean return value do something unexpected.
Author of Reactor, DelayLight, SiteSensor, Rachio, Deus Ex Machina II, Intesis WMP Gateway, Auto Virtual Thermostat and VirtualSensor plugins. Vera Plus w/100+ Z-wave devices. Vera3, Lite. Hassio, Slapdash.

Offline rafale77

  • Community Beta
  • Hero Member
  • ******
  • Posts: 1749
  • Karma: +101/-27
  • HA ≠ IoT as a blue sky is cloudless.
Re: Is RETURN essential at end of scene script?
« Reply #2 on: January 12, 2019, 09:08:43 pm »
Learning something here. Most of my lua code actually does not close with a return statement and I have never seen anything bad from it. Then they are almost all on openLuup so it might be different. The only return statements I have are conditionals for the entire scene.
openLuup (79 devices, 141 scenes, 19 apps) master to VeraPlus (142 zwave nodes, 8 Zigbee nodes, 221 devices,  20 scenes , 2 apps) +  Hubitat (15 Zigbee nodes) + Home-Assistant (API Integrations). Bridged to Siri and Alexa. Homewave. VeraPlus ExtRooted and mios server independent.

Offline rigpapa

  • Beta Testers
  • Hero Member
  • *****
  • Posts: 1121
  • Karma: +187/-3
Re: Is RETURN essential at end of scene script?
« Reply #3 on: January 12, 2019, 09:58:40 pm »
Learning something here. Most of my lua code actually does not close with a return statement and I have never seen anything bad from it. Then they are almost all on openLuup so it might be different. The only return statements I have are conditionals for the entire scene.

openLuup we can see and verify. The version I'm running (2018.11.21) has the following test of the scene Lua return value (which it receives into the local variable ok): if ok == false

This means that the scene Lua return value has to be exactly boolean type value false (and nothing else) to prevent the scene actions from running. Anything else returned, including nothing/nil, will allow the scene to run. So akbooer has, predictably, chosen the safest implementation.

But that may not be Vera's implementation, and perhaps some testing will reveal clues about what they do. If their test of the return value is, for example, if not sceneReturnVal, then Lua would stop the scene actions for boolean false, but also stop it if the scene returned nothing/nil. It would run the scene actions if the scene returned 1 or "1", which are common Luup values meaning true/on, but it would also run them if the scene Lua returned 0 or "0" (common Luup values meaning false/off) because in Lua (5.1) all logical operators accept false or nil as false and anything else as true.

So, I'm diving a bit here, but where I'm going is this, back to my original statement, if you always return true or false, the result is always predictable and safe (on both Vera and openLuup).
Author of Reactor, DelayLight, SiteSensor, Rachio, Deus Ex Machina II, Intesis WMP Gateway, Auto Virtual Thermostat and VirtualSensor plugins. Vera Plus w/100+ Z-wave devices. Vera3, Lite. Hassio, Slapdash.

Offline UKsub

  • Jr. Member
  • **
  • Posts: 51
  • Karma: +0/-1
Re: Is RETURN essential at end of scene script?
« Reply #4 on: January 13, 2019, 10:53:46 am »
Thanks for the replies.

Similarly, is it valid or might it cause a problem to close script with just *return* without being followed by true or false?

Offline akbooer

  • Beta Testers
  • Master Member
  • *****
  • Posts: 6387
  • Karma: +292/-70
  • "Less is more"
Re: Is RETURN essential at end of scene script?
« Reply #5 on: January 13, 2019, 10:59:31 am »
@rigpapa

As described, boolean false is the ONLY return value which will stop a scene.  openLuup is like this because Vera does this.

As per standard Lua, return at the end of a function is implicit, and the same as writing return nil.
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P, 9x Philips Hue,
Razberry, MySensors Arduino, HomeWave, AltUI, AltHue, DataYours, Grafana, openLuup, ZWay, ZeroBrane Studio.

Offline rigpapa

  • Beta Testers
  • Hero Member
  • *****
  • Posts: 1121
  • Karma: +187/-3
Re: Is RETURN essential at end of scene script?
« Reply #6 on: January 13, 2019, 01:13:17 pm »
As described, boolean false is the ONLY return value which will stop a scene.  openLuup is like this because Vera does this.

Yes, I've now confirmed this via testing, so that is the definitive answer: IT IS NOT NECESSARY FOR A SCENE TO RETURN TRUE; IT MAY RETURN FALSE.

I stand corrected that returning true is necessary. I still think it's advisable/good style, but it's not strictly necessary.

Quote
As per standard Lua, return at the end of a function is implicit, and the same as writing return nil.

Actually, this statement is not correct, and I think it was you who actually previously identified where in Luup this is troublesome, but to clarify:

It depends entirely on how the code receiving the return values is structured. A return at the end of a function (implicit or otherwise) with no return values returns nothing, and that is different from returning nil. A more correct statement would be: all functions return a list of values, which may be empty. If the function has a return statement with no values, or contains no return statement (implicit return), then the return list is empty (zero length). Otherwise, the return list has length equal to the number of values in the return statement, and nil is a valid value. Thus return on its own returns a list of zero length, but return nil returns a list of length==1, where the one value is nil.

The fact that you get nil when receiving return values into variables is an artifact of how the return list is assigned to the variables. All return variables are assigned ordinally--the first return value to the first receiving variable, the second return value to the second variable, etc. If a return variable's ordinal position exceeds the length of the return list, it is explicitly assigned nil; if the return list is longer than the receiving variables list, the excess return values are simply ignored.
Code: [Select]
function test()
    return "a", "b"
end

local a,b,c,d = test()
print(a,b,c,d) -- prints: A       B       nil     nil

But in other contexts, the realities of Lua implementation are apparent. Take the case of a function wrapping another function, like: tostring( test2() ):

Code: [Select]
function test2()
    return -- nothing
end

-- This fails!
print( tostring( test2() ) ) -- runtime error: stdin:1: bad argument #1 to 'tostring' (value expected)

-- But this works, because the receiver is assigned nil by list assignment
returnval = test2()
print(returnval) -- prints: nil

So you can see that by receiving the function return into a variable (or variables), it APPEARS to return nil, but that's not actually what is happening, and the fact that returnval gets nil is an artifact/side-effect of the code structure, not how Lua actually returns values from a function.

And a further example showing this (adding code to the previous example):
Code: [Select]
function howmany(...)
    print("I see", #arg, " arguments!")
end

howmany( test2() ) -- prints: I see   0       arguments!

Again, I believe it was you that pointed out at least one example in Luup where an empty return list (nothing) is returned, rather than nil. I don't recall what function that was, but I know luup.variable_get() is such a culprit--if you request a variable for which the service or variable does not exist in user_data, the function returns nothing, and passing that directly to another function (like tostring()) will get you into hot water. And of course, that same function is troublesome for functions like tonumber() for a similar reason: it returns more than one value, but most people ignore that, and so many code examples people pass around receive only the first return value that I think most people aren't even really aware that the function returns multiple values. But they quickly find out when they attempt to do the apparently sensible but actually incorrect tonumber( luup.variable_get( service, name, devnum ) ) (which doesn't work as expected and should never be done).
Author of Reactor, DelayLight, SiteSensor, Rachio, Deus Ex Machina II, Intesis WMP Gateway, Auto Virtual Thermostat and VirtualSensor plugins. Vera Plus w/100+ Z-wave devices. Vera3, Lite. Hassio, Slapdash.

Offline akbooer

  • Beta Testers
  • Master Member
  • *****
  • Posts: 6387
  • Karma: +292/-70
  • "Less is more"
Re: Is RETURN essential at end of scene script?
« Reply #7 on: January 13, 2019, 01:38:28 pm »
Again, I believe it was you that pointed out at least one example in Luup where an empty return list (nothing) is returned, rather than nil.

Yes, you're right that I did.
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P, 9x Philips Hue,
Razberry, MySensors Arduino, HomeWave, AltUI, AltHue, DataYours, Grafana, openLuup, ZWay, ZeroBrane Studio.