15

When I define a command that defines commands

\def\makefoobar{
  \def\foo{foo}
  \def\bar{bar}
}

and prefix it with \global

{ \global\makefoobar }

it is treated like

{
  \global\def\foo{foo}
  \def\bar{bar}
}

keeping the \global effect only to the first definition, or more precise, the first token of \makefoobar, may this be a definition or not.

Is there a way to define \makefoobar so that modifiers like \global or \long would affect all macros defined within, or can I only define a global alternative command \gmakefoobar?

1
  • 1
    Short answer: no; prefixes like \global, \long, \outer and \protected (the last one is in e-TeX) only apply to the next token (and they do expansion because a proper token should follow them). – egreg Apr 2 '15 at 20:44
18

You could use

{ \globaldefs=1 \makefoobar }

All assignments are global while \globadefs is non zero. Beware though, lots of things will break with the setting, use with care.

3
  • +1 Thank you for teaching me \globaldefs. Seems like I skipped it when reading TeXbook. – Henri Menke Apr 2 '15 at 19:54
  • I indeed fear things may break with \globaldefs, especially when the macro used may include other macros, which would then be affected as well, and was thus hoping for a solution to propagate the \global into own macros. Last resort would be to define a \gmakefoobar similar to \gdef. – XZS Apr 2 '15 at 19:56
  • @XZS the setting of \globaldefs is itself local so if used as above it only affects the two definitions inside your macro – David Carlisle Apr 2 '15 at 20:00
8
\def\makefoobar#1{%
  #1\def\foo{foo}%
  #1\def\bar{bar}%
}

Now you can use one of

\makefoobar{}
\makefoobar{\global}
\makefoobar{\global\long}

or all the other combinations.

The prefixes \global, \long, \outer and \protected (the last one only if the engine uses e-TeX extensions) only apply to the next token and they do expansion because they must be followed by a proper token.

We could add an abstraction layer.

\def\multipledef#1#2{%
  \def#1##1{\def\prefixes{##1}#2}%
}
\def\pdef{\prefixes\def}

\multipledef\makefoobar{%
  \pdef\foo{foo}%
  \pdef\bar{bar}%
}

% tests follow

\makefoobar{}
\show\foo\show\bar

{\makefoobar{\global\long}}
\show\foo\show\bar

\makefoobar{\protected}
\show\foo\show\bar

Here's the session on the terminal (compile with pdftex because of \protected):

> \foo=macro:
->foo.
l.12 \show\foo
              \show\bar
? 
> \bar=macro:
->bar.
l.12 \show\foo\show\bar

? 
> \foo=\long macro:
->foo.
l.15 \show\foo
              \show\bar
? 
> \bar=\long macro:
->bar.
l.15 \show\foo\show\bar

? 
> \foo=\protected macro:
->foo.
l.18 \show\foo
              \show\bar
? 
> \bar=\protected macro:
->bar.
l.18 \show\foo\show\bar

? 

Not the answer you're looking for? Browse other questions tagged or ask your own question.