0

我希望能够使用MoonScript为ComputerCraft制作程序,但由于 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代码中缩短它?

4

3 回答 3

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
于 2013-07-22T23:17:27.313 回答
1

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

  • 如果您想使用moonscript 中可用的“类”概念,那么无论如何您都必须编写所有这些步骤(否则您会得到一个具有不同“类”行为的“类”)。
  • 不同之处在于,在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 时更新代码。
于 2013-10-22T21:30:16.537 回答
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

于 2013-04-30T19:37:42.573 回答