lua-users home
lua-l archive

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


On Tue, May 5, 2009 at 9:47 PM, David Manura wrote:
> I think it would be ideal if we could inject only lexically (the
> injection limited to the lexical scope)...
> modify the string metatable to be scope aware...

A cleaner solution to that can be achieved in Metalua.  The Metalua
solution has been added to the MethodChainingWrapper page.

A test example of it goes like this:

  -{extension "lexicalindex"}

  -- test example libraries
  local stringx = {}
  function stringx.trim(self)  return self:match('^%s*(%S*)%s*$') end

  local function f(o,k)
    if type(o) == 'string' then return stringx[k] or string[k] end
    return o[k]
  end

  local function test(s)
    assert(s.trim == nil)
    lexicalindex f
    assert(s.trim ~= nil)
    assert(s:trim():upper() == 'TEST')
  end
  local s = '  test  '
  assert(s.trim == nil)
  test(s)
  assert(s.trim == nil)

print 'DONE'


The above gets transformed by Metalua into this corresponding plain Lua code:


  --- $ ./build/bin/metalua -S vs.lua
  --- Source From "@vs.lua": ---
  local function __li_invoke (__li_index, o, name, ...)
     return __li_index (o, name) (o, ...)
  end

  local stringx = { }

  function stringx:trim ()
     return self:match "^%s*(%S*)%s*$"
  end

  local function f (o, k)
     if type (o) == "string" then
        return stringx[k] or string[k]
     end
     return o[k]
  end

  local function test (s)
     assert (s.trim == nil)
     local __li_index = f
     assert (__li_index (s, "trim") ~= nil)
     assert (__li_invoke (__li_index, __li_invoke (__li_index, s,
"trim"), "upper") == "TEST")
  end

  local s = "  test  "

  assert (s.trim == nil)

  test (s)

  assert (s.trim == nil)


As seen, the index (including method call) operations inside the
current scope are transformed into function call operations specified
by the user.


[1] http://lua-users.org/wiki/MethodChainingWrapper