Вывод Lua для классов moonscript - МАССИВНЫЙ

Я хотел бы иметь возможность создавать программы для ComputerCraft с использованием MoonScript, но из-за того, что CC помещается в "песочницу" для предотвращения проблем безопасности на серверах Minecraft и т. Д., Я не могу напрямую запрашивать moonscript и запускать оттуда код moonscript. Я должен преобразовать мой код moonscript в lua.

Однако это проблематично из-за того, что реализация класса для moonscript очень велика и не очень консервативна по размеру файла. Когда я набираю "класс 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.2.4: http://leafo.net/posts/moonscript_v024.html

Класс теперь минимально выглядит так

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

Просто глядя на код, я могу удалить некоторые мертвые пути из-за _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).

Вы не можете сократить это в своем коде moonscript. Но вы, возможно, сможете обработать вывод вручную довольно тривиально для рефакторинга общих частей. Стоит ли это делать? Учти это:

  • Если вы хотите использовать понятие "класс" в том виде, в каком оно доступно в moonscript, вам все равно придется кодировать все эти шаги (в противном случае вы получите "класс" с другим поведением "класса").
  • Разница в том, что в 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 будет обновляться легче.
Другие вопросы по тегам