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\xyzallerede er definert, utsteder en advarsel, men utfører definisjonen uansett. Selvfølgelig\defgir 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.
#optionali eksemplet ditt? Har du en referanse for hvor jeg kan lese mer om disse?luat-mac.lua(for kontekst) ogluatex-preprocessor.luafor Luatex-Plain. Hth.\definee-TeX beskyttet. For å ha det utvidbart må man bruke\defineexpandable(eller vanlig\def).