[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: A guide to building Lua modules
- From: Philipp Janda <siffiejoe@...>
- Date: Wed, 16 Apr 2014 10:12:06 +0200
Am 16.04.2014 09:28 schröbte steve donovan:
Although I'd say the primary motive for string methods is not
polymorphism but convenient laziness ;)
Depending on the coding style there is not that much convenience
involved, e.g.:
`s_gsub( s, "x", "y" )` vs. `s:gsub( "x", "y" )` (three more characters
including a space).
Hmm, interesting! I didn't think of that ... Now only the issue with
sandboxing remains.
Alas, that metatable is still globally shared per Lua state[1], so it
violates the "Don't mess with other people's code rule"
Now, using something like Lanes allows you to work with multiple
states conveniently - and this kind of thing becomes more attractive.
There's also rings, which avoids the whole threading mess ...
[1] but, if it was indexed relative to the "thread" - the currently
running coroutine - we would have some more freedom to go wild - or
get really hardass restrictive...
I'm not sure that would help much. Consider function `a` in module `A`
written by author X calls function `b` in module `B` written by author
Y. Now X wants to provide function `a` in a sandboxed environment. Until
now everything is fine because `a` has its own upvalues and environment
(as does `b`), so this is safe, _but_ what if `b` uses method syntax for
string operations?! You replaced/disabled the string metatable for the
sandboxed code, so when `a` is called you need to restore the string
metatable for `b` and disable it afterwards[*]. Things get more
complicated when the sandboxed code passes a function argument via `a`
to `b`. You would need to wrap that function argument to
disable/reenable string metamethods on entry/exit.
If your head doesn't hurt yet, imagine your sandboxed code is allowed to
use coroutines and yield from withing the callback ...
At this point I would probably just reimplement `b` without method syntax.
Philipp
[*]: That can be automated:
local orig_mt = debug.getmetatable( "" )
local function swrap_helper( mt, ok, ... )
debug.setmetatable( "", mt )
if ok then
return ...
else
error( (...) )
end
end
local function swrap( f )
return function( ... )
local mt = debug.getmetatable( "" )
debug.setmetatable( "", orig_mt )
return swrap_helper( mt, pcall( f, ... ) )
end
end
sandboxed_a = swrap( a )