Er det noen forskjell mellom å definere en variabel ved hjelp av \def
og å bruke \define
, når det brukes uten et tall i parentes, f.eks \def\somecommand{\percent}
og \define\somecommand{\percent}
? Kan jeg alltid bruke \define
på steder der \def
kan brukes?
Kommentarer
- Fra det jeg ser,
\define\xyz{...}
, når\xyz
allerede er definert, utsteder en advarsel, men utfører definisjonen uansett. Selvfølgelig\def
gir ikke ' ingen advarsler.
Svar
For referanse: Det er to definisjoner av \define
: Den første i syst-aux.mkiv viser atferden Egreg nevnte i sin kommentar: hvis makroen allerede er definert, lar den den være som den er. (En følgesvenn, \redefine
lar deg overskrive den gjeldende definisjonen av makro uansett om den er i bruk.) Ironisk nok blir denne foreløpige definisjonen overskrevet uten notat så snart formatet lastes inn core-sys.mkiv (mens \redefine
forblir for alltid).
definisjon av \define
makroen som er gitt av brukergrensesnittet, sjekker ikke bare for tidligere definerte kontrollsekvenser med samme navn, men fungerer også som en slags kort notasjon for obligatoriske argumenter. Den har skjemaet
\define [<digit>] <macro> {<definition>}
der det første argumentet, et siffer, angir antall argumenter den nye makroen skal akseptere. Åpenbart kan dette resultere i kortere definisjoner. Til sammenligning krever velgeren
\def\sevenofnine#1#2#3#4#5#6#7#8#9{#7} \starttext \sevenofnine abcdefghi\par \stoptext
noe mindre å skrive med \define
makroen:
\define[9]\sevenofnine{#7}
Dermed kan disse definisjonene resultere i mer lesbar kode – noe som alltid er bra når du skriver TEX.
Dessverre er \define
wrapper tar bort en god del av uttrykksevnen til ren \def
. I kontekst vil du ha lagt merke til at makroer som tar valgfrie argumenter er vanlige med hensyn til brukergrensesnittet. For eksempel kan du ganske enkelt ikke erstatte den andre \def
inisjonen under kodebiten med et tilsvarende uttrykk ved hjelp av \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
Det er fordi du med \define
ikke kan spesifisere argumentavgrensere (her: parenteser) som er nødvendige for valgfrie argumenter, så i utgangspunktet er makroene dine bare begrenset til å ta obligatoriske argumenter. Av samme grunn er det ingen måte å definere billige \{start|stop}something
-miljøer heller:
\let\stopfoo\relax \def\startfoo#1\stopfoo{\bgroup\bold#1\egroup} %%% ^^^^^^^^ not possible \starttext \startfoo bar \stopfoo \stoptext
(Brukergrensesnittet for dette er \definestartstop
(jf. core-sys.mkiv ), uansett.)
Endelig, i dag, den viktigste ulempen med \define
er at det ikke tillater argumenter for mkvi -stil. Det er rett og slett ingen måte å referere til en parameter med navn hvis du ikke kan tilordne den i utgangspunktet.
% 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
Så hvis du vil gjøre seriøs makroskriving, vil du snart lære å unngå \define
, mens det er trygt for mindre komplekse oppgaver.
#optional
i eksemplet ditt? Har du en referanse for hvor jeg kan lese mer om disse?luat-mac.lua
(for kontekst) ogluatex-preprocessor.lua
for Luatex-Plain. Hth.\define
e-TeX beskyttet. For å ha det utvidbart må man bruke\defineexpandable
(eller vanlig\def
).