Close
    Search Search

    Módulo: Argumentos

    Módulo: Argumentos A documentação para este modelo está disponível em Módulo: Argumentos na página da web pagepedia.

    Este módulo fornece processamento fácil de argumentos passados ​​de #invoke. É um metamódulo, destinado ao uso por outros módulos e não deve ser chamado diretamente de #invoke. Seus recursos incluem:

    • Corte fácil de argumentos e remoção de argumentos em branco.
    • Os argumentos podem ser transmitidos pelo quadro atual e pelo quadro pai ao mesmo tempo. (Mais detalhes abaixo).
    • Os argumentos podem ser transmitidos diretamente de outro módulo Lua ou do console de depuração.
    • Os argumentos são buscados conforme necessário, o que pode ajudar a evitar (alguns) problemas com tags ref.
    • A maioria dos recursos pode ser personalizada.

    Conteúdo

    Uso básico

    Primeiro, você precisa carregar o módulo. Ele contém uma função, chamada getArgs.



    getArgs local = require ('Módulo: Argumentos'). getArgs

    No cenário mais básico, você pode usar getArgs dentro de sua função principal. A variável args é uma tabela que contém os argumentos de #invoke. (Veja abaixo para detalhes.)

    local getArgs = require ('Módulo: Argumentos'). getArgs local p = {} função p.main (frame) local args = getArgs (frame) - O código do módulo principal vai aqui. fim retorno p


    No entanto, a prática recomendada é usar uma função apenas para processar argumentos de #invoke. Isso significa que se alguém chamar seu módulo de outro módulo Lua, você não precisa ter um objeto de quadro disponível, o que melhora o desempenho.


    local getArgs = require ('Módulo: Argumentos'). getArgs local p = {} função p.main (frame) local args = getArgs (frame) return p._main (args) end function p._main (args) - Principal o código do módulo vai aqui. fim retorno p

    Se você deseja que várias funções usem os argumentos, e também deseja que eles sejam acessíveis a partir de #invoke, você pode usar uma função de empacotador.

    local getArgs = require ('Módulo: Argumentos'). getArgs função local makeInvokeFunc (funcName) função de retorno (frame) local args = getArgs (frame) return p [funcName] (args) end end local p = {} p.func1 = makeInvokeFunc ('_ func1') function p._func1 (args) - O código para a primeira função vai aqui. end p.func2 = makeInvokeFunc ('_ func2') function p._func2 (args) - O código para a segunda função vai aqui. fim retorno p

    Opções

    As seguintes opções estão disponíveis. Eles são explicados nas seções abaixo.

    local args = getArgs (frame, {trim = false, removeBlanks = false, valueFunc = function (key, value) - Código para processar um argumento end, frameOnly = true, parentOnly = true, parentFirst = true, wrappers = {'Template : Um modelo de wrapper ',' Modelo: Outro modelo de wrapper '}, readOnly = true, noOverwrite = true})

    Corte e remoção de espaços em branco

    Argumentos em branco geralmente confundem programadores novos na conversão de templates de páginas Mediaweb para Lua. Na sintaxe do modelo, strings em branco e strings que consistem apenas em espaços em branco são consideradas falsas. No entanto, em Lua, strings em branco e strings que consistem em espaços em branco são consideradas verdadeiras. Isso significa que, se você não prestar atenção a esses argumentos ao escrever seus módulos Lua, poderá tratar algo como verdadeiro que, na verdade, deve ser tratado como falso. Para evitar isso, por padrão, este módulo remove todos os argumentos em branco.



    Da mesma forma, o espaço em branco pode causar problemas ao lidar com argumentos posicionais. Embora o espaço em branco seja cortado para argumentos nomeados vindos de #invoke, ele é preservado para argumentos posicionais. Na maioria das vezes, esse espaço em branco adicional não é desejado, portanto, este módulo o corta por padrão.

    No entanto, às vezes você deseja usar argumentos em branco como entrada e às vezes deseja manter espaços em branco adicionais. Isso pode ser necessário para converter alguns modelos exatamente como foram escritos. Se quiser fazer isso, você pode definir os argumentos trim e removeBlanks como false.

    args local = getArgs (frame, {trim = false, removeBlanks = false})

    Formatação personalizada de argumentos

    Às vezes, você deseja remover alguns argumentos em branco, mas não outros, ou talvez queira colocar todos os argumentos posicionais em letras minúsculas. Para fazer coisas como essa, você pode usar a opção valueFunc. A entrada para esta opção deve ser uma função que recebe dois parâmetros, chave e valor, e retorna um único valor. Este valor é o que você obterá quando acessar a chave do campo na tabela args.

    Exemplo 1: esta função preserva espaços em branco para o primeiro argumento posicional, mas apara todos os outros argumentos e remove todos os outros argumentos em branco.

    local args = getArgs (frame, {valueFunc = function (key, value) if key == 1 then return value elseif value then value = mw.text.trim (value) if value ~ = '' then return value end end return nil fim })

    Exemplo 2: esta função remove os argumentos em branco e converte todos os argumentos em minúsculas, mas não remove os espaços em branco dos parâmetros posicionais.



    local args = getArgs (frame, {valueFunc = function (key, value) se não for value then return nil end value = mw.ustring.lower (value) if mw.ustring.find (value, '% S') então return value end return nil end})

    Nota: as funções acima irão falhar se a entrada for passada que não seja do tipo string ou nil. Esse pode ser o caso se você usar a função getArgs na função principal do seu módulo e essa função for chamada por outro módulo Lua. Nesse caso, você precisará verificar o tipo de entrada. Isso não é um problema se você estiver usando uma função especialmente para argumentos de #invoke (ou seja, você tem funções p.main e p._main ou algo semelhante).

    Exemplos 1 e 2 com verificação de tipo 1 exemplo:

    args local = getArgs (frame, {valueFunc = function (key, value) if key == 1 then return value elseif type (value) == 'string' then value = mw.text.trim (value) if value ~ = ' 'então valor de retorno else return nil end else valor de retorno end end})

    2 exemplo:

    local args = getArgs (frame, {valueFunc = function (key, value) if type (value) == 'string' then value = mw.ustring.lower (value) if mw.ustring.find (value, '% S' ) então valor de retorno else return nil end else valor de retorno end end})

    Além disso, observe que a função valueFunc é chamada mais ou menos toda vez que um argumento é solicitado da tabela args, portanto, se você se preocupa com o desempenho, certifique-se de não fazer nada ineficiente com seu código.

    Quadros e quadros principais

    Os argumentos na tabela args podem ser transmitidos do quadro atual ou de seu quadro pai ao mesmo tempo. Para entender o que isso significa, é mais fácil dar um exemplo. Digamos que temos um módulo chamado Module: ExampleArgs. Este módulo imprime os dois primeiros argumentos posicionais que são passados.

    Módulo: código ExampleArgs

    local getArgs = require ('Módulo: Argumentos'). getArgs local p = {} função p.main (frame) local args = getArgs (frame) return p._main (args) end função p._main (args) local first = args [1] ou '' local segundo = args [2] ou '' retornar primeiro .. '' .. segundo fim retornar p

    Módulo: ExampleArgs é então chamado por Template: ExampleArgs, que contém o código {{#invoke: ExampleArgs | main | firstInvokeArg}}. Isso produz o resultado "firstInvokeArg".

    Agora, se chamássemos Template: ExampleArgs, aconteceria o seguinte:

    Código Resultado
    {{ExampleArgs}} firstInvokeArg
    {{ExampleArgs|firstTemplateArg}} firstInvokeArg
    {{ExampleArgs|firstTemplateArg|secondTemplateArg}} firstInvokeArg secondTemplateArg

    Existem três opções que você pode definir para alterar esse comportamento: frameOnly, parentOnly e parentFirst. Se você definir frameOnly, apenas os argumentos passados ​​do frame atual serão aceitos; se você definir parentOnly, apenas os argumentos passados ​​do quadro pai serão aceitos; e se você definir parentFirst, os argumentos serão passados ​​dos quadros atual e pai, mas o quadro pai terá prioridade sobre o quadro atual. Aqui estão os resultados em termos de Template: ExampleArgs:

    frameOnly
    Código Resultado
    {{ExampleArgs}} firstInvokeArg
    {{ExampleArgs|firstTemplateArg}} firstInvokeArg
    {{ExampleArgs|firstTemplateArg|secondTemplateArg}} firstInvokeArg
    parentOnly
    Código Resultado
    {{ExampleArgs}}
    {{ExampleArgs|firstTemplateArg}} firstTemplateArg
    {{ExampleArgs|firstTemplateArg|secondTemplateArg}} firstTemplateArg secondTemplateArg
    parentFirst
    Código Resultado
    {{ExampleArgs}} firstInvokeArg
    {{ExampleArgs|firstTemplateArg}} firstTemplateArg
    {{ExampleArgs|firstTemplateArg|secondTemplateArg}} firstTemplateArg secondTemplateArg

    :

    1. Se você definir as opções frameOnly e parentOnly, o módulo não buscará nenhum argumento de #invoke. Provavelmente não é isso que você deseja.
    2. Em algumas situações, um quadro pai pode não estar disponível, por exemplo, se getArgs for passado o quadro pai em vez do quadro atual. Nesse caso, apenas os argumentos do quadro serão usados ​​(a menos que parentOnly seja definido, caso em que nenhum argumento será usado) e as opções parentFirst e frameOnly não terão efeito.

    Wrappers

    A opção wrappers é usada para especificar um número limitado de modelos como modelos de wrapper, ou seja, modelos cujo único propósito é chamar um módulo. Se o módulo detectar que está sendo chamado a partir de um modelo de wrapper, ele verificará apenas os argumentos no quadro pai; caso contrário, ele verificará apenas os argumentos no quadro passado para getArgs. Isso permite que os módulos sejam chamados por #invoke ou por meio de um modelo de wrapper sem a perda de desempenho associada à necessidade de verificar o quadro e o quadro pai para cada consulta de argumento.

    Os invólucros podem ser especificados como uma string ou como uma matriz de strings.

    local args = getArgs (frame, {wrappers = 'Template: Wrapper template'})


    local args = getArgs (frame, {wrappers = {'Template: Wrapper 1', 'Template: Wrapper 2', - Qualquer número de modelos de wrapper pode ser adicionado aqui.}})

    :

    1. O módulo detectará automaticamente se ele está sendo chamado a partir de uma subpágina de modelo de wrapper / sandbox, portanto, não há necessidade de especificar as páginas de sandbox explicitamente.
    2. A opção wrappers efetivamente altera o padrão das opções frameOnly e parentOnly. Se, por exemplo, parentOnly fosse explicitamente definido como false com wrappers definidos, as chamadas por meio de modelos de wrapper resultariam no carregamento de ambos os argumentos frame e pai, embora as chamadas que não fossem feitas por meio de modelos de wrapper resultassem no carregamento apenas de argumentos de frame.
    3. Se a opção de wrappers estiver definida e nenhum quadro pai estiver disponível, o módulo sempre obterá os argumentos do quadro passado para getArgs.

    Escrevendo na tabela args

    Às vezes, pode ser útil gravar novos valores na tabela args. Isso é possível com as configurações padrão deste módulo. (No entanto, tenha em mente que geralmente é melhor estilo de codificação criar uma nova tabela com seus novos valores e copiar argumentos da tabela args conforme necessário.)

    args.foo = 'algum valor'

    É possível alterar esse comportamento com as opções readOnly e noOverwrite. Se readOnly for definido, não será possível gravar nenhum valor na tabela args. Se noOverwrite for definido, é possível adicionar novos valores à tabela, mas não é possível adicionar um valor se isso substituir quaisquer argumentos passados ​​de #invoke.

    Tags de referência

    Este módulo usa meta-tabelas para buscar argumentos de #invoke. Isso permite acesso aos argumentos do quadro e aos argumentos do quadro pai sem usar a função pairs (). Isso pode ajudar se seu módulo puder receber tags ref como entrada.

    Assim que as tags ref são acessadas de Lua, elas são processadas pelo software da página Mediaweb e a referência aparecerá na lista de referências no final do artigo. Se o seu módulo continuar a omitir a tag de referência da saída, você terminará com uma referência fantasma - uma referência que aparece na lista de referências, mas nenhum número que se vincule a ela. Isso tem sido um problema com módulos que usam pairs () para detectar se devem usar os argumentos do quadro ou do quadro pai, já que esses módulos processam automaticamente todos os argumentos disponíveis.

    Este módulo resolve esse problema permitindo o acesso aos argumentos do quadro e do quadro pai, ao mesmo tempo em que busca esses argumentos apenas quando for necessário. O problema ainda ocorrerá se você usar pares (args) em outro lugar em seu módulo, no entanto.

    limitações conhecidas

    O uso de meta-tabelas também tem suas desvantagens. A maioria das ferramentas normais de tabela Lua não funcionam corretamente na tabela args, incluindo o operador #, a função next () e as funções na biblioteca de tabelas. Se usar isso é importante para o seu módulo, você deve usar sua própria função de processamento de argumento em vez deste módulo.

    - Este módulo fornece fácil processamento de argumentos passados ​​para Scribunto de - #invoke. Ele se destina ao uso por outros módulos Lua e não deve ser - chamado diretamente de #invoke. local libraryUtil = require ('libraryUtil') local checkType = libraryUtil.checkType local arguments = {} - Gere quatro funções tidyVal diferentes, para que não tenhamos que verificar as opções - toda vez que chamá-lo. função local tidyValDefault (chave, val) if type (val) == 'string' then val = val: match ('^% s * (.-)% s * $') if val == '' then return nil else return val end else return val end end função local tidyValTrimOnly (key, val) if type (val) == 'string' then return val: match ('^% s * (.-)% s * $') else return val end end local function tidyValRemoveBlanksOnly (key, val) if type (val) == 'string' then if val: find ('% S') then return val else return nil end else return val end end local function tidyValNoChange (key, val ) return val end função local matchTitle (fornecido, título) local tp = tipo (fornecido) return (tp == 'string' ou tp == 'número') e mw.title.new (fornecido) .prefixedText == title end local translate_mt = {__index = function (t, k) return k end} function arguments.getArgs (frame, options) checkType ('getArgs', 1, frame, 'table', true) checkType ('getArgs', 2, options , 'tabela', verdadeiro) frame = frame ou {} options = options ou {} - [[- Configure a tradução do argumento. -]] options.translate = options.translate ou {} if getmetatable (options.translate) == nil then setmetatable (options.translate, translate_mt) end if options.backtranslate == nil then options.backtranslate = {} para k , v em pares (options.translate) faça options.backtranslate [v] = k end end if options.backtranslate e getmetatable (options.backtranslate) == nil then setmetatable (options.backtranslate, {__index = function (t, k) if options.translate [k] ~ = k then return nil else return k end end}) end - [[- Obtenha as tabelas de argumentos. Se nos foi passado um objeto de quadro válido, obtenha os - argumentos do quadro (fargs) e os argumentos do quadro pai (pargs), dependendo - das opções definidas e da disponibilidade do quadro pai. Se não tivéssemos passado - passamos um objeto de quadro válido, estamos sendo chamados de outro módulo Lua - ou do console de depuração, então suponha que recebemos uma tabela de args - diretamente e atribua-a a uma nova variável (luaArgs). -]] fargs, pargs, luaArgs locais if type (frame.args) == 'table' e type (frame.getParent) == 'function' then if options.wrappers then - [[- A opção wrappers torna Módulo: Os argumentos procuram argumentos em - na tabela de argumentos do quadro ou na tabela de argumentos pai, mas - não em ambas. Isso significa que os usuários podem usar a sintaxe #invoke - ou um modelo de wrapper sem a perda de desempenho associada - procurando argumentos no quadro e no quadro pai. - Módulo: os argumentos procurarão argumentos no quadro pai - se encontrar o título do quadro pai em options.wrapper; - caso contrário, ele irá procurar argumentos no objeto frame passado - para getArgs. -]] local parent = frame: getParent () se não pai então fargs = frame.args else local title = parent: getTitle (): gsub ('/ sandbox $', '') local found = false if MatchTitle (options .wrappers, title) then found = true elseif type (options.wrappers) == 'table' then for _, v em pares (options.wrappers) faça if matchTitle (v, title) then found = true break end end end - - Testamos o falso especificamente aqui para que nil (o padrão) aja como verdadeiro. if found or options.frameOnly == false then pargs = parent.args end if not found or options.parentOnly == false then fargs = frame.args end end else - options.wrapper não está definido, então verifique as outras opções . senão options.parentOnly then fargs = frame.args end if not options.frameOnly then local parent = frame: getParent () pargs = parent and parent.args ou nil end end if options.parentFirst then fargs, pargs = pargs, fargs end else luaArgs = frame end - Define a ordem de precedência das tabelas de argumentos. Se as variáveis ​​forem - nil, nada será adicionado à tabela, que é como evitamos conflitos - entre os argumentos frame / pai e os argumentos Lua. local argTables = {fargs} argTables [#argTables + 1] = pargs argTables [#argTables + 1] = luaArgs - [[- Gere a função tidyVal. Se tiver sido especificado pelo usuário, nós - usamos isso; caso contrário, escolhemos uma das quatro funções, dependendo das opções - escolhidas. Isso é para que não tenhamos que chamar a tabela de opções - toda vez que a função for chamada. -]] local tidyVal = options.valueFunc if tidyVal then if type (tidyVal) ~ = 'function' then error ("valor incorreto atribuído à opção 'valueFunc'" .. '(função esperada, obteve' .. tipo (tidyVal) .. ')', 2) end elseif options.trim ~ = false then if options.removeBlanks ~ = false then tidyVal = tidyValDefault else tidyVal = tidyValTrimOnly end else if options.removeBlanks ~ = false then tidyVal = endyValRemoveBlanks = tidyValRemoveBlanks - [[- Configure as tabelas args, metaArgs e nilArgs. args será aquele - acessado a partir das funções, e metaArgs conterá os argumentos reais. Nil - os argumentos são memorizados em nilArgs, e a metatabela conecta todos eles - juntos. -]] local args, metaArgs, nilArgs, metatable = {}, {}, {}, {} setmetatable (args, metatabela) função local mergeArgs (tabelas) - [[- Aceita várias tabelas como entrada e mescla seus chaves e valores - em uma tabela. Se um valor já estiver presente, ele não será sobrescrito; - as tabelas listadas anteriormente têm precedência. Também estamos memorizando valores nulos, que podem ser substituídos se forem 's' (soft). -]] para _, t em ipairs (tabelas) faça para chave, val em pares (t) faça if metaArgs [chave] == nil e nilArgs [chave] ~ = 'h' then local tidiedVal = tidyVal (chave, val) if tidiedVal == nil then nilArgs [key] = 's' else metaArgs [key] = tidiedVal end end end end end end - [[- Definir o comportamento da metatabela. Os argumentos são memorizados na tabela metaArgs, - e só são buscados nas tabelas de argumentos uma vez. Buscar argumentos - das tabelas de argumentos é o passo que mais consome recursos neste - módulo, então tentamos evitá-lo sempre que possível. Por esse motivo, os argumentos nil também são memorizados na tabela nilArgs. Além disso, mantemos um registro - na metatabela de quando pares e ipairs foram chamados, portanto não - executamos pares e ipairs nas tabelas de argumento mais de uma vez. Nós também - não executamos ipairs em fargs e pargs se os pares já foram executados, como todos - os argumentos já terão sido copiados. -]] metatabela .__ index = function (t, key) - [[- Busca um argumento quando a tabela args é indexada. Primeiro, verificamos - para ver se o valor foi memorizado e, se não, tentamos buscá-lo - nas tabelas de argumentos. Quando verificamos a memoização, precisamos verificar - metaArgs antes de nilArgs, já que ambos podem ser não nulos ao mesmo tempo. - Se o argumento não estiver presente no metaArgs, também verificamos se - os pares já foram executados. Se os pares já foram executados, retornamos nulo. - Isso ocorre porque todos os argumentos já terão sido copiados para - metaArgs pela função mergeArgs, o que significa que quaisquer outros argumentos - devem ser nulos. -]] if type (key) == 'string' then key = options.translate [key] end local val = metaArgs [key] if val ~ = nil then return val elseif metatable.donePairs ou nilArgs [key] then return nil end for _, argTable in ipairs (argTables) do local argTableVal = tidyVal (key, argTable [key]) if argTableVal ~ = nil then metaArgs [key] = argTableVal return argTableVal end end nilArgs [key] = 'h' return nil end metatabela .__ newindex = function (t, key, val) - Esta função é chamada quando um módulo tenta adicionar um novo valor à tabela - args, ou tenta alterar um valor existente. if type (key) == 'string' then key = options.translate [key] end if options.readOnly then error ('não foi possível gravar na chave da tabela de argumento "' .. tostring (chave) .. '"; a tabela é somente leitura', 2) elseif options.noOverwrite and args [key] ~ = nil then error ('não foi possível gravar na chave da tabela de argumento"' .. tostring (chave) .. '"; não é permitido sobrescrever argumentos existentes', 2) elseif val == nil then - [[- Se o argumento for sobrescrito com nil, precisamos apagar - o valor em metaArgs, de modo que __index, __pairs e __ipairs não - usam um valor existente anterior, se presente; e também precisamos - memoize o nil em nilArgs, de modo que o valor não seja procurado nas tabelas de argumento se for acessado novamente. -]] metaArgs [chave] = nil nilArgs [chave] = 'h' else metaArgs [chave] = val end end local função translatenext (invariante) local k, v = próximo (invariante.t, invariante.k) invariante. k = k if k == nil then return nil elseif type (k) ~ = 'string' or not options.backtranslate then return k, v else local backtranslate = options.backtranslate [k] if backtranslate == nil then - Skip Este. Esta é uma chamada final, portanto, não causará estouro de pilha retornar translatenext (invariante) senão retornar backtranslate, v end end end metatabela .__ pares = função () - Chamado quando os pares são executados na tabela args. if not metatable.donePairs then mergeArgs (argTables) metatable.donePairs = true end return translatenext, {t = metaArgs} end local function inext (t, i) - Isso usa nosso metamétodo __index local v = t [i + 1] se v ~ = nil então retorna i + 1, v end end metatabela .__ ipairs = function (t) - Chamado quando ipairs é executado na tabela args.

    Adicione um comentário do Módulo: Argumentos
    Comentário enviado com sucesso! Vamos analisá-lo nas próximas horas.