Использование varargs в более ранней версии Lua, но требуется совместимость с 5.2+



В настоящее время я пишу код для плагина Lightroom. Lightroom не использует версию 5.2. У меня есть следующая функция, которая прекрасно работает в настоящее время, но я обеспокоен, как если Lightroom обновится до более новой версии, этот код будет сломан. Есть ли у вас предложения по обеспечению обработки varargs в этом случае независимо от версии lua?



Следующий код проверяет, используется ли функция F в качестве ключа в таблице needsModule. Если да, то он составляет функцию это включает в себя вызов изменения модулей на значение, указанное ключом F, за которым следует вызов функции F и ее аргументов.

local function wrapFOM(F,...)
local openModule = needsModule[F]
if openModule == nil then
return function() return F(unpack(arg)) end
end
return function()
if LrApplicationView.getCurrentModuleName() ~= openModule then
LrApplicationView.switchToModule(openModule)
end
return F(unpack(arg)) --proper tail call
end
end
526   2  
lua

2 ответов:

Lua 5.1 и выше поддерживают новый стиль обработки vararg:

function vfunc( ... )
  for i = 1, select( '#', ... )
    print( i, (select( i, ... )) )
  end
end

Или если вы действительно хотите, чтобы varargs в новой выделенной таблице каждый вызов функции (остерегайтесь аргументов nil):

function vfunc( ... )
  local args = {...}
  for i, v in ipairs( args ) do
    print( i, v )
  end
end

Если Вам также нужна поддержка Lua 5.0, вам не повезло, потому что ... вне списка параметров является синтаксической ошибкой. Вам придется прибегнуть к условной генерации кода, чтобы обойти это:

-- newer Lua versions use load instead of loadstring
local loadstring = loadstring or load
-- feature test for Lua 5.1+
local supports_ellipsis = loadstring( "return ..." ) ~= nil
local args = supports_ellipsis and "{...}" or "arg"

function vararg( n, f )
  local t = {}
  for i = 1, n do t[ i ] = "_"..i end
  local params = table.concat( t, ", ", 1, n )
  local code = [[
return function( f )
  return function( ]]..params..[[, ... )
    return f( ]]..params..", "..args..[[ )
  end
end
]]
  return assert( loadstring( code, "=(vararg)" ) )()( f )
end

Используйте его так:

-- two fixed parameters, third parameter holds vararg list
local vfunc = vararg( 2, function( a, b, arg )
  print( a, b )
  for i,v in ipairs( arg ) do
    print( "", i, v )
  end
end )

vfunc( "a" )
vfunc( "a", "b" )
vfunc( "a", "b", "c" )
vfunc( "a", "b", "c", "d" )

Интерфейс функции vararg выше может работать даже для более ранних версий Lua, но вам, вероятно, потребуется отдельная реализация в отдельном файле, потому что языки слишком сильно отличаются.

В соответствии с Lightroom SDK 4 Руководство для программистов (PDF):

Lightroom 4 использует версию 5.1.4 языка Lua.

Поскольку Lua 5.1 поддерживает как старый стиль, так и новый стиль varargs, я думаю, что вы можете просто использовать новый стиль и не беспокоиться о прямой совместимости.

Comments

    Ничего не найдено.