moonscript类的Lua输出是MASSIVE

时间:2013-04-30 13:52:36

标签: lua moonscript

我希望能够使用ComputerCraftMoonScript创建一个程序,但是由于CC的沙盒方式可以防止Minecraft服务器上的安全问题,我不能直接需要moonscript并从那里运行moonscript代码。我必须将我的moonscript代码转换为lua。

然而,这是有问题的,因为moonscript的类实现非常大,并且不是非常文件化保守的。当我输入“class Bacon”时,它会输出lua:

local Bacon
do
  local _parent_0 = nil
  local _base_0 = { }
  _base_0.__index = _base_0
  if _parent_0 then
    setmetatable(_base_0, _parent_0.__base)
  end
  local _class_0 = setmetatable({
    __init = function(self, ...)
      if _parent_0 then
        return _parent_0.__init(self, ...)
      end
    end,
    __base = _base_0,
    __name = "Bacon",
    __parent = _parent_0
  }, {
    __index = function(cls, name)
      local val = rawget(_base_0, name)
      if val == nil and _parent_0 then
        return _parent_0[name]
      else
        return val
      end
    end,
    __call = function(cls, ...)
      local _self_0 = setmetatable({}, _base_0)
      cls.__init(_self_0, ...)
      return _self_0
    end
  })
  _base_0.__class = _class_0
  if _parent_0 and _parent_0.__inherited then
    _parent_0.__inherited(_parent_0, _class_0)
  end
  Bacon = _class_0
  return _class_0
end

这适用于每个类的实现,这有点荒谬。有什么方法可以在我的moonscript代码中缩短这个吗?

3 个答案:

答案 0 :(得分:8)

在最新版本中,生成的代码量已经被清理了很多,0.2.4:http://leafo.net/posts/moonscript_v024.html#code_generation_changes

现在一个类看起来像这样

local Hello
do
  local _base_0 = { }
  _base_0.__index = _base_0
  local _class_0 = setmetatable({
    __init = function() end,
    __base = _base_0,
    __name = "Hello"
  }, {
    __index = _base_0,
    __call = function(cls, ...)
      local _self_0 = setmetatable({}, _base_0)
      cls.__init(_self_0, ...)
      return _self_0
    end
  })
  _base_0.__class = _class_0
  Hello = _class_0
end

答案 1 :(得分:1)

只是查看代码,我可以删除因_parent_0为零而导致的一些死路径

local Bacon
do
  local _base_0 = { }
  _base_0.__index = _base_0
  local _class_0 = setmetatable({
    __init = function(self, ...)
    end,
    __base = _base_0,
    __name = "Bacon",
  }, {
    __index = function(cls, name)
       return rawget(_base_0, name)
    end,
    __call = function(cls, ...)
      local _self_0 = setmetatable({}, _base_0)
      cls.__init(_self_0, ...)
      return _self_0
    end
  })
  _base_0.__class = _class_0
  Bacon = _class_0
  return _class_0
end

您可以找到一个静态分析器为您执行此操作。

否则,如果它是纯粹的代码大小(以字节为单位),那么请使用压缩器(例如Squish

答案 2 :(得分:1)

您无法在moonscript代码中缩短此内容。但是您可以手动对输出进行后处理,而不是简单地重构公共部分。值得做吗?考虑一下:

  • 如果你想使用moonscript中提供的“class”概念,那么你必须编写所有这些步骤(否则你得到一个具有不同“class”行为的“class”)。
  • 不同之处在于,在moonscript中,N个类会导致你发布的代码的N个副本,每个只有两行不同,而如果你手动实现moonscript的类概念,你可能会使用一个函数来定义类,因为在一些Lua OO库中完成:Bacon = newClass(“Bacon”)将调用上面的代码,并适当地替换“__name =”和“Bacon =”行。
  • 因此,通过复制moonscript代码而不是手动编写代码,每个类需要20行代码(最新的moonscript)。但除非你的课程是微不足道的,否则它们可能会包含比20行更多的代码,可能是200行。
  • 因此,虽然您确实每个类重复18行,但这可能不到您必须编写的代码的10%。
  • 但这是一个假设。如果假设是错误的,那么问题是,为什么你需要在第一个地方上课?只需使用基于带有':'糖的表的基本Lua对象。

如果您真的想使用moonscript输出,我认为您唯一的选择是手动重构它。您发布的代码可以放在一个函数中,只需要将两行更改为类名的参数化。

请注意,将moonscript生成的Lua代码重复留在Lua文件中有几个优点,至少对于经常使用的操作(类定义可能不是其中之一,但moonscript不仅仅是这样):

  • 它削减了函数调用;这可能会提高速度,因为无需将变量推送到堆栈,调用函数,将返回值放入堆栈,读取堆栈,将堆栈值弹出堆栈)。速度增加是否明显将取决于代码被调用的频率。
  • 它更易于维护:如果操作正确,当moonscript更容易更新时,您可以更新代码。