Existe alguma diferença entre definir uma variável usando \def
e \define
, quando usado sem um número entre colchetes, por exemplo \def\somecommand{\percent}
e \define\somecommand{\percent}
? Posso sempre usar \define
em locais onde \def
pode ser usado?
Comentários
Resposta
Para referência: existem duas definições de \define
: a primeira em syst-aux.mkiv mostra o comportamento que Egreg citado em seu comentário: se a macro já estiver definida, ela deixa como está. (Um complemento, \redefine
permite que você sobrescreva a definição atual de macro, independentemente de ela estar em uso.) Ironicamente, esta definição preliminar é sobrescrita sem aviso assim que o formato é carregado > core-sys.mkiv (enquanto \redefine
permanece para sempre).
O real a definição da macro \define
conforme fornecida pela interface do usuário não só verifica as sequências de controle definidas anteriormente com o mesmo nome, mas também serve como algum tipo de notação curta para argumentos obrigatórios. Ele tem o esquema
\define [<digit>] <macro> {<definition>}
onde o primeiro argumento, um dígito, especifica o número de argumentos que a nova macro vai aceitar. Obviamente, isso pode resultar em definições mais curtas. Para comparação, o seletor
\def\sevenofnine#1#2#3#4#5#6#7#8#9{#7} \starttext \sevenofnine abcdefghi\par \stoptext
requer menos digitação com a macro \define
:
\define[9]\sevenofnine{#7}
Portanto, essas definições podem resultar em um código mais legível – o que é sempre uma boa coisa ao escrever TEX.
Infelizmente, o \define
o wrapper tira uma boa parte da expressividade dos \def
simples. No Contexto, você deve ter notado, macros que usam argumentos opcionais são comuns em relação à interface do usuário. Por exemplo, você simplesmente não pode substituir a segunda \def
iniciação no snippet abaixo por uma expressão equivalente usando \define
:
\unprotect \def\myfoo{\dosingleempty\do_my_foo} \def\do_my_foo[#1]#2{% \iffirstargument{\bf\WORD#1}\fi #2\par% } \protect \starttext \myfoo{bar} \myfoo[foo]{bar} \stoptext
Isso porque com \define
você não pode especificar os delimitadores de argumento (aqui: colchetes) necessários para argumentos opcionais, portanto, basicamente, suas macros são limitadas a aceitar apenas argumentos obrigatórios (colchetes). Pela mesma razão, não há como definir ambientes \{start|stop}something
baratos:
\let\stopfoo\relax \def\startfoo#1\stopfoo{\bgroup\bold#1\egroup} %%% ^^^^^^^^ not possible \starttext \startfoo bar \stopfoo \stoptext
(A interface do usuário para isso é \definestartstop
(cf. core-sys.mkiv ), de qualquer maneira.)
Finalmente, hoje em dia a desvantagem mais importante de \define
é que não permite argumentos no estilo mkvi . Simplesmente não há como se referir a um parâmetro por seu nome se você não puder atribuí-lo em primeiro lugar.
% macros=mkvi \unprotect \def\foo{\dosingleempty\do_foo} \def\do_foo[#optional]#mandatory{% \bgroup\sansbold#optional\space\egroup #mandatory\par% } \protect \starttext \foo{bar} \foo[foo]{bar} \stoptext
Então, se você quiser escrever macros a sério, em breve aprenderá a evitar \define
, embora seja seguro para tarefas menos complexas.
Comentários
- Obrigado por esta resposta útil. Esclarecimento: quando você diz " argumentos no estilo mkiv ", isso significa argumentos nomeados, como
#optional
em seu exemplo? Você tem uma referência para onde eu possa ler mais sobre isso? - @LarsH Sim, macros Mk VI (não MkIV!) São aquelas com nomes de parâmetros (opcionais). Não tenho certeza se existe qualquer documentação de nível de usuário além da fonte: o código do pré-processador pode ser encontrado em
luat-mac.lua
(para Contexto) eluatex-preprocessor.lua
para Luatex-Plain. Hth. - Desculpe, erro meu.
- Não ' sei se era esse o caso no momento em que escrevi esta resposta, mas hoje as macros definidas usando
\define
são protegidas pelo e-TeX. Para que seja expansível, é necessário usar\defineexpandable
(ou simples\def
).
\define\xyz{...}
, quando\xyz
já está definido, emite um aviso, mas executa a definição de qualquer forma. É claro que\def
não ' emite nenhum aviso.