lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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 )