Módulo:Testes/Gkiyoshinishimoto/Arguments/doc

Origem: Wikipédia, a enciclopédia livre.


Este módulo fornece processamento fácil de argumentos passados a partir de #invoke. Ele é um metamódulo, destinado ao uso por outros módulos, e não deve ser chamado diretamente a partir de #invoke (para um módulo que pode ser invocado diretamente por predefinições, você pode querer dar uma olhada em {{#invoke:Testes/Gkiyoshinishimoto/Params}}). Suas características incluem:

  • Corte fácil de argumentos e remoção de argumentos em branco.
  • Os argumentos podem ser passados pelo quadro atual e pelo quadro parental ao mesmo tempo. (Mais detalhes abaixo.)
  • Os argumentos podem ser passados diretamente a partir de outro módulo Lua ou a partur do console de depuração.
  • A maioria dos recursos pode ser personalizada.

Uso básico[editar código-fonte]

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

local getArgs = require('Módulo:Testes/Gkiyoshinishimoto/Arguments').getArgs

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

local getArgs = require('Módulo:Testes/Gkiyoshinishimoto/Arguments').getArgs
local p = {}

function p.main(frame)
	local args = getArgs(frame)
	-- O código do módulo principal vai aqui.
end

return p

Prática recomendada[editar código-fonte]

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

local getArgs = require('Módulo:Testes/Gkiyoshinishimoto/Arguments').getArgs
local p = {}

function p.main(frame)
	local args = getArgs(frame)
	return p._main(args)
end

function p._main(args)
	-- O código do módulo principal vai aqui.
end

return p

A maneira como isso é chamado a partir de uma predefinição é {{#invoke:Testes/Gkiyoshinishimoto/Exemplo|main}} (opcionalmente com alguns parâmetros como {{#invoke: Testes/Gkiyoshinishimoto/Exemplo|main|arg1=valor1|arg2=valor2}}), e a maneira como isso é chamado a partir de um módulo é require('Módulo:Testes/Gkiyoshinishimoto/Exemplo')._main ({arg1 = 'valor1', arg2 = valor2, 'arg3 espaçado' = 'valor3'}). O que este segundo faz é construir uma tabela com os argumentos nela, então dá essa tabela para a função p._main(args), que a usa nativamente.

Múltiplas funções[editar código-fonte]

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 "wrapper".

local getArgs = require('Módulo:Testes/Gkiyoshinishimoto/Arguments').getArgs

local p = {}

local function makeInvokeFunc(funcName)
	return function (frame)
		local args = getArgs(frame)
		return p[funcName](args)
	end
end

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.
end

return p

Opções[editar código-fonte]

As seguintes opções estão disponíveis. Elas são explicadas 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 = {
		'Predefinição:Uma predefinição wrapper',
		'Predefinição:Outra predefinição wrapper'
	},
	readOnly = true,
	noOverwrite = true
})

Aparar e remover espaços em branco[editar código-fonte]

Os argumentos em branco geralmente atrapalham os codificadores novos na conversão de predefinições MediaWiki para Lua. Na sintaxe de predefinições, sequências[a] em branco e sequências[a] consistindo apenas em espaços em branco são consideradas falsas. No entanto, em Lua, sequências[a] em branco e sequências[a] consistindo 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 deveria ser tratado como falso. Para evitar isso, por padrão, este módulo remove todos os argumentos em branco.

Da mesma forma, os espaços em branco podem causar problemas ao lidar com argumentos posicionais. Embora o espaço em branco seja cortado para argumentos nomeados provenientes de "#invoke", ele é preservado para argumentos posicionais. Na maioria das vezes, esse espaço em branco adicional não é desejado, portanto, esse módulo o elimina 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 algumas predefinições exatamente como foram escritas. Se quiser fazer isso, você pode definir os argumentos trim e removeBlanks como false.

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

Formatação personalizada de argumentos[editar código-fonte]

À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 assim, você pode usar a opção valueFunc. A entrada para esta opção deve ser uma função que usa dois parâmetros, key e value, e retorna um único valor. Este valor é o que você obterá ao acessar o campo key na tabela args.


Exemplo 1: esta função preserva o espaço em branco para o valor do primeiro argumento posicional, mas corta o valor de 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
	end
})

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

local args = getArgs(frame, {
	valueFunc = function (key, value)
		if not value then
			return nil
		end
		value = mw.ustring.lower(value)
		if mw.ustring.find(value, '%S') then
			return value
		end
		return nil
	end
})

Observação: as funções acima falharão se forem passadas entradas que não sejam do tipo string ou nil. Este 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. Neste caso, você precisará verificar o tipo de sua entrada. Isso não é um problema se você estiver usando uma função especialmente para argumentos a partir de "#invoke" (ou seja, você tem as funções p.main e p._main ou algo semelhante).

Exemplos 1 e 2 com verificação de tipo

Exemplo 1:

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

Exemplo 2:

local args = getArgs(frame, {
	valueFunc = function (key, value)
		if type(value) == 'string' then
			value = mw.ustring.lower(value)
			if mw.ustring.find(value, '%S') then
				return value
			else
				return nil
			end
		else
			return value
		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 está fazendo nada ineficiente com seu código.

Quadros e quadros parentais[editar código-fonte]

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

Código de Módulo:Testes/Gkiyoshinishimoto/ExampleArgs
local getArgs = require('Módulo:Testes/Gkiyoshinishimoto/Arguments').getArgs
local p = {}

function p.main(frame)
	local args = getArgs(frame)
	return p._main(args)
end

function p._main(args)
	local first = args[1] or ''
	local second = args[2] or ''
	return first .. ' ' .. second
end

return p

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

Agora, se fôssemos chamar Predefinição:Teste/Gkiyoshinishimoto/ExampleArgs, aconteceria o seguinte:

Código Resultado
{{Teste/Gkiyoshinishimoto/ExampleArgs}} firstInvokeArg
{{Teste/Gkiyoshinishimoto/ExampleArgs|firstTemplateArg}} firstInvokeArg
{{Teste/Gkiyoshinishimoto/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, somente os argumentos passados do quadro atual serão aceitos; se você definir parentOnly, somente os argumentos passados do quadro parental serão aceitos; e se você definir parentFirst, os argumentos serão passados dos quadros atual e parental, mas o quadro parental terá prioridade sobre o quadro atual. Aqui estão os resultados em termos de Predefinição:Teste/Gkiyoshinishimoto/ExampleArgs:

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

Notas:

  1. Se você definir as opções frameOnly e parentOnly, o módulo não buscará nenhum argumento a partir de #invoke. Provavelmente não é isso que você deseja.
  2. Em algumas situações, um quadro parental pode não estar disponível, por exemplo: se "getArgs" for passado para o quadro parental 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[editar código-fonte]

A opção "wrappers" é utilizada para especificar um número limitado de predefinições como "predefinições wrapper", ou seja, predefinições cujo único objetivo é chamar um módulo. Se o módulo detectar que está sendo chamado de uma predefinição "wrapper", ele verificará apenas os argumentos no quadro parental; caso não, ele verificará apenas os argumentos no quadro passado para "getArgs". Isso permite que os módulos sejam chamados por "#invoke" ou por meio de uma predefinição "wrapper" sem a perda de desempenho associada à verificação do quadro e do quadro parental para cada pesquisa de argumento.

Por exemplo, o único conteúdo de Predefinição:Teste/Gkiyoshinishimoto/Side box (excluindo o conteúdo em marcações[b] <noinclude>...</noinclude>) é {{#invoke:Testes/Gkiyoshinishimoto/Side box|main}}. Não faz sentido verificar os argumentos passados diretamente para a instrução "#invoke" para esta predefinição, pois nenhum argumento será especificado lá. Podemos evitar a verificação de argumentos passados para "#invoke" usando a opção "parentOnly", mas se fizermos isso, "#invoke" também não funcionará em outras páginas. Se for esse o caso, o |text=Algum texto no código {{#invoke:Testes/Gkiyoshinishimoto/Side box|main|text=Algum texto}} seria completamente ignorado, independentemente da página a partir da qual foi usado. Usando a opção wrappers para especificar 'Predefinição:Teste/Gkiyoshinishimoto/Side box' como um wrapper, podemos fazer com que {{#invoke:Testes/Gkiyoshinishimoto/Side box|main|text=Algum texto}} funcione na maioria das páginas, embora ainda não exija que o módulo verifique os argumentos na própria página Predefinição:Teste/Gkiyoshinishimoto/Side box.

Os wrappers podem ser especificados como uma sequência[a] ou como um arranjo de sequências[a].

local args = getArgs(frame, {
	wrappers = 'Predefinição:Predefinição wrapper'
})


local args = getArgs(frame, {
	wrappers = {
		'Predefinição:Predefinição wrapper 1',
		'Predefinição:Predefinição wrapper 2',
		-- Qualquer número de predefinições "wrapper" pode ser adicionado aqui.
	}
})

Notas:

  1. O módulo detectará automaticamente se está sendo chamado a partir da subpágina "/Testes" de uma predefinição "wrapper", portanto, não há necessidade de especificar páginas de testes explicitamente.
  2. A opção "wrappers" altera efetivamente o padrão das opções "frameOnly" e "parentOnly". Se, por exemplo, "parentOnly" for definida explicitamente como 0 com "wrappers" definida, as chamadas por meio de predefinições wrappers resultariam no carregamento de argumentos parentais e de quadro, embora as chamadas que não sejam por meio de predefinições wrappers resultariam apenas em argumentos de quadro sendo carregados.
  3. Se a opção "wrappers" estiver definida e nenhum quadro parental estiver disponível, o módulo sempre obterá os argumentos do quadro passado para getArgs.

Escrevendo na tabela "args"[editar código-fonte]

Algumas vezes pode ser útil escrever novos valores na tabela "args". Isso é possível com as configurações padrões 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 definida, não será possível gravar nenhum valor na tabela "args". Se noOverwrite for definida, é possível adicionar novos valores à tabela, mas não é possível adicionar um valor se ele substituir quaisquer argumentos passados de "#invoke".

Marcações "ref"[editar código-fonte]

Este módulo usa metatabelas para buscar argumentos a partir de "#invoke". Isso permite acesso aos argumentos do quadro e aos argumentos do quadro parental sem usar a função pairs(). Isso pode ajudar se seu módulo pode ter passado marcações{{Nre|nome=tag}{<ref>...</ref> como entrada.

Assim que as marcações[b] <ref>...</ref> são acessadas a partir de Lua, elas são processadas pelo software MediaWiki e a referência aparecerá na lista de referências na parte inferior do artigo. Se o seu módulo continuar omitindo a marcação[b] de referência da saída, você terminará com uma referência fantasma – uma referência que aparece na lista de referência, mas sem nenhum número vinculado a ela. Este tem sido um problema com módulos que usam pairs() para detectar se devem usar os argumentos do quadro ou do quadro parental, já que esses módulos processam automaticamente todos os argumentos disponíveis.

Este módulo resolve este problema permitindo o acesso aos argumentos do quadro e do quadro parental, enquanto ainda busca esses argumentos apenas quando necessário. No entanto, o problema ainda ocorrerá se você usar pairs(args) em outro lugar em seu módulo.

Limitações conhecidas[editar código-fonte]

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

Notas[editar código-fonte]

  1. a b c d e f do inglês strings
  2. a b c do inglês tag

Ver também[editar código-fonte]