Lua对Moonscript类的输出非常庞大。

我想要用 MoonScript 为 ComputerCraft 写一个程序,但是由于 CC 沙箱机制的限制,我不能直接 require 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 代码中缩短它?

点赞
用户282536
用户282536

我刚刚查看代码,因为_parent_0是 nil,所以我可以删除一些无用的路径...

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)。

2013-04-30 19:37:42
用户127833
用户127833

最新版本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
2013-07-22 23:17:27
用户869951
用户869951

将下面翻译成中文并且保留原本的 markdown 格式

你没有办法在你的 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 输出,我认为你唯一的选择是手动进行重构。你贴出的代码可以放入一个函数中,只需要更改两行以适应类名参数。

请注意,在你的 Lua 文件中保留 moonscript 生成的 Lua 代码副本有几个优点,至少对于常用操作(类定义可能不是其中之一,但是 moonscript 可以做更多):

  • 它缩短了函数调用;这很可能会增加速度,因为不需要将变量推入堆栈,调用函数,将返回值放在堆栈上,读取堆栈,从堆栈中弹出值。速度的提高是否显著取决于代码被调用的频率。
  • 它更易于维护:如果正确地执行,你可以在 moonscript 更新时更容易地更新代码。
2013-10-22 21:30:16