将LuaJ与Scala一起使用

时间:2013-11-19 22:01:46

标签: scala lua luaj

我正在尝试将LuaJ与Scala一起使用。大多数事情都有效(实际上,如果你正确地完成它们,所有事情都会工作!)但是由于Scala的setter实现,设置对象值的简单任务变得异常复杂。

Scala的:

class TestObject {
  var x: Int = 0
}

的Lua:

function myTestFunction(testObject) 
  testObject.x = 3
end

如果我执行包含此Lua函数的脚本或行并将TestObject的强制实例传递给myTestFunction,则会在LuaJ中导致错误。 LuaJ试图直接写入值,而Scala要求你通过隐式定义的setter(使用可怕的名字x_ =,这是无效的Lua,所以即使尝试将其称为函数也会使你的Lua无法解析)

正如我所说,有一些解决方法,例如定义自己的setter或使用@BeanProperty标记。他们只是编写应该更容易编写的代码:

的Lua:

function myTestFunction(testObject) 
  testObject.setX(testObject, 3)
end

有没有人知道让luaj隐式调用setter进行此类赋值的方法?或者我可能会在luaj源代码中查找或许实现这样的事情?

谢谢!

2 个答案:

答案 0 :(得分:1)

我必须承认我对LuaJ并不太熟悉,但我想到的第一件事就是将对象包装在代理表中以简化与API的交互。根据您的需求,此解决方案可能是最好的,也可能不是最好的,但它可能是一个很好的临时解决方案。

local mt = {}

function mt:__index(k)
    return self.o[k] -- Define how your getters work here.
end

function mt:__newindex(k, v)
    return self.o[k .. '_='](v) -- "object.k_=(v)"
end

local function proxy(o)
    return setmetatable({o = o}, mt)
end

-- ...

function myTestFunction(testObject) 
    testObject = proxy(testObject)
    testObject.x = 3
end

我认为这可能是解决问题的最不具侵入性的方法。至于修改LuaJ的源代码以更好地满足您的需求,我快速浏览了文档和源代码,找到了thisthisthis。我最好的猜测是,如果Scala需要一种不同的设置值的方式,line 71 of JavaInstance.java就是你需要改变的地方。

    f.set(m_instance, CoerceLuaToJava.coerce(value, f.getType()));

答案 1 :(得分:0)

也许您应该使用方法语法:

testObject:setX(3)

注意冒号':'而不是点'。在一些编辑中很难区分。

这与函数调用具有相同的效果:

testObject.setX(testObject, 3)

但更具可读性。

它也可以用于在类上调用静态方法:

luajava.bindClass("java.net.InetAddress"):getLocalHost():getHostName()

'左边的部分:'被评估一次,所以声明如

x = abc[d+e+f]:foo()

将被评估为

local tmp = abc[d+e+f]
x = tmp.foo(tmp)