Closed catfact closed 4 years ago
yeah, i see a bunch more.
typing
for k,v in pairs(_G) do print(k..' : '..tostring(v)) end
in the REPL (on a fresh start), yields this list of suspects:
obviously some come from lua core (print
, etc.) but yeah, here's to rationalizing the rest. 👍
well a lot of them are c functions defined in matron. I don't actually know if there's a way to collect these in a table from c. If not maybe they should at least have a special naming convention
can't we just use lint to detect unsanctioned globals in the scripts?
perhaps c functions can use a preceding underscore?
most of the rest of the globals can be cleaned up and put into the norns
table. midi and grids still have some possible things to work out re: convenience functions
perhaps c functions can use a preceding underscore?
obfuscated names would help for sure. better still would be not to pollute the namespace at all. i'm not up on how the c/lua integration works but my hunch is there's got to be a way to specify an env that's not _G
.
finally, assuming we can't make the globals go away we could consider tailoring the env used in scripts to hide or protect access to globals. (poc started in #426.)
i'm not up on how the c/lua integration works
a forward pointer for anyone following along (who like me doesn't know their way around quite yet):
looking at the lua manual, i see there's a bunch of suggestively named stuff in the C API (lua_newtable
, lua_setmetatable
, etc.). anyway, maybe the pieces are all there?
(caveat: just browsing around and haven't actually tried anything yet.)
ok, i think the solution would use lua_pushcfunction and lua_setfield
( to register C functions as fields in a single table)
btw i am checking out this book, which is a little tedious but seems to have many useful nuggets https://www.safaribooksonline.com/library/view/creating-solid-apis/9781491986301/
user trickyflemming was just hit by this on lines:
I was finally bitten by the globals last night. I was working on a script and I created an array called metro. Hoo boy, norns did not like that. The error text was not useful so it took a bit of hunting to figure out what happened. I had to replace the offending variable, resave the script, and then reboot norns to fix it.
the lvm reset fixes that are in flight would make this a little better (i think metro
would get reset on the next script run, or?) but it may be worth talking through something like the shadow ENV idea in #436.
i have LVM reset working now! it's great. just trying to prune unneeded code now
that's cool - but a word of caution - resetting the LVM isn't actually a solution for the main failure case we've seen so far - which is users accidentally overwriting system globals. e.g. this problem: https://llllllll.co/t/norns-development/14073/214?u=zebra
resetting the LVM seems useful for two reasons:
it certainly clears out the global namespace between script launches, with a heavy hammer indeed. i have vague reservations about nuking everything between scripts, but we can see how it goes, with special eye on timer and peripheral device management.
it could be a useful kind of panic button connected directly to maiden
(like, a special websocket command in matron
, not thtrough lua), or even to a hardware button press combo. so that you can get out of a broken state without power cycling. (this was what i thought the request was for.)
but for the case where someone makes a global script variable called metro
, nuking the LVM state doesn't help at all. for this we still need a sandboxing environment layer for scripts. PR #436 looks pretty good to me for that. it covers the situation where i do a global metro = foo
assignment in a script. it unfortunately doesn't cover the situation where i assign to a field of metro
without declaring it first: metro[0] = foo
. that seems like a hard class of error to guard against given that scripts do need to be able to access fields in the module - it would require some metatable stuff in the metro.lua
module itself, to make certain things "read-only." the effort/reward seems not worth it, at this time.
the idea from the forum of adding norns sysgtem globals to maiden syntax highlighting, also seems like a smart thing to do and not too difficult.
i am confused how resetting the LVM wouldn't fix a mistaken renaming of metro
.
of course it's not going to fix the broken script, but this to me seems a different issue entirely. either we explicitly require every single script to require
everything they need, or have some default globals that users need to know not to overwrite.
that said, #436 seems very elegant, and doesn't have the issue of my current LVM reset PR (re: device detection). is there any downside to #436? if not we should just go with that and abandon this LVM reset business. i should still make an attempt to refine the script loading (which i did in the LVM reset PR)
to be sure i understand correctly, i'm looking at PR #448 and running a script now seems to go like this:
Script.savestate()
to write the requested filename and system state to system.lua
on the filesystem.startup.lua
, read system.lua
, and load the requested script file on startup.let's say the startup script assigns metro = foo
. startup.lua
executes metro = require 'metro'
, then the script says metro = foo
, and metros are broken. they would be broken in the same way if we rebooted. this is why system global clobbering is so bad - user script can put the norns in a basically unbootable state with a very simple error.
the only way out of this is not letting user scripts overwrite system globals.
anyway yes, i think PR #436 seems more apropos to the problem at hand, i don't see any downside, and i have other concerns about the lua reset. (see new issue.)
re: dev detect, yes would simply need a new facility in weaver to explicitly request a report of all connected devices. device_scan
only reports new devices.
there are way too many globals and they aren't defined in any particular place. it's a recipe for disaster. not even just in user scripts but when we want to extend or maintain the system.
in the beginning, there was the
norns
table, and it was global. it had to be, so that the C API glue could see it and call its fields.then, there were more globals added for convenient usage in scripts and REPL. this was controvesial, but at least they were collected in one place (
globals.lua
) and commented withldoc.
now, i don't know what happened to
globals.lua
but the definition of globals has gone everywhere- many are instartup.lua
, which makes sense: https://github.com/monome/norns/blob/master/lua/startup.lua#L9-L31but many are in
script.lua
(i think? can't tell! that's the whole problem in a nutshell) https://github.com/monome/norns/blob/master/lua/startup.lua#L9-L31and probably elsewhere. this is really bonkers because
script.lua
is otherwise structured as a module!