xkeyval `boolkey` setting is persistent across macro calls: scope leak?
Clash Royale CLAN TAG#URR8PPP
up vote
4
down vote
favorite
I thought that keyval
arguments to macros were supposed to be confined in their macro scope, but the following code:
documentclassreport
usepackagexkeyval
% Define a custom command option using `boolkey`
makeatletter
define@boolkeymyCommandoption[true] % one boolean option
newcommandmyCommand[2]%
setkeysmyCommand#1%
ifoption%
textbf#2%
else%
#2%
fi%
makeatother
begindocument
myCommandnot bold % default behaviour is not to bold
myCommand[option]bold % explicitly set option to bold
myCommandnot bold % fail! default behaviour was expected!
myCommand[option=false]not bold % workaround that makes the "default" concept useless
enddocument
produces:
Why? Am I missing something?
Is there a way to get this default behaviour working regardless of previous calls to the macro?
macros key-value xkeyval scoping default
 |Â
show 1 more comment
up vote
4
down vote
favorite
I thought that keyval
arguments to macros were supposed to be confined in their macro scope, but the following code:
documentclassreport
usepackagexkeyval
% Define a custom command option using `boolkey`
makeatletter
define@boolkeymyCommandoption[true] % one boolean option
newcommandmyCommand[2]%
setkeysmyCommand#1%
ifoption%
textbf#2%
else%
#2%
fi%
makeatother
begindocument
myCommandnot bold % default behaviour is not to bold
myCommand[option]bold % explicitly set option to bold
myCommandnot bold % fail! default behaviour was expected!
myCommand[option=false]not bold % workaround that makes the "default" concept useless
enddocument
produces:
Why? Am I missing something?
Is there a way to get this default behaviour working regardless of previous calls to the macro?
macros key-value xkeyval scoping default
3
There is no group inmyCommand
. So the scope of the code inmyCommand
is the same for all invocations in the example. You can add a group yourself withbegingroup
andendgroup
.
â moewe
Sep 3 at 10:38
@moewe Oh, so you mean it is my responsibility to close the scope ofmyCommand
. This works indeed, thanks :) Is an extra pair ofequivalent to
begingroup endgroup
?
â iago-lito
Sep 3 at 10:47
2
remember that this is a macro expansion language not a functional programming language, macro definitions are essentially just expanded inline and there is no scope associated with them.
â David Carlisle
Sep 3 at 11:24
@DavidCarlisle That is true. When we get into concepts like "optional default keyworded arguments", it is easy to tend to forget XD
â iago-lito
Sep 3 at 11:26
2
@iago-lito it's a "uniquely interesting" macro expansion language:-) for your other question if being used for groupingis more or less the same as
begingroupendgroup
unless you are in math mode, butcan be used for more things, eg delimiting arguments that
begingroup
can not be used for, so it depends....
â David Carlisle
Sep 3 at 11:28
 |Â
show 1 more comment
up vote
4
down vote
favorite
up vote
4
down vote
favorite
I thought that keyval
arguments to macros were supposed to be confined in their macro scope, but the following code:
documentclassreport
usepackagexkeyval
% Define a custom command option using `boolkey`
makeatletter
define@boolkeymyCommandoption[true] % one boolean option
newcommandmyCommand[2]%
setkeysmyCommand#1%
ifoption%
textbf#2%
else%
#2%
fi%
makeatother
begindocument
myCommandnot bold % default behaviour is not to bold
myCommand[option]bold % explicitly set option to bold
myCommandnot bold % fail! default behaviour was expected!
myCommand[option=false]not bold % workaround that makes the "default" concept useless
enddocument
produces:
Why? Am I missing something?
Is there a way to get this default behaviour working regardless of previous calls to the macro?
macros key-value xkeyval scoping default
I thought that keyval
arguments to macros were supposed to be confined in their macro scope, but the following code:
documentclassreport
usepackagexkeyval
% Define a custom command option using `boolkey`
makeatletter
define@boolkeymyCommandoption[true] % one boolean option
newcommandmyCommand[2]%
setkeysmyCommand#1%
ifoption%
textbf#2%
else%
#2%
fi%
makeatother
begindocument
myCommandnot bold % default behaviour is not to bold
myCommand[option]bold % explicitly set option to bold
myCommandnot bold % fail! default behaviour was expected!
myCommand[option=false]not bold % workaround that makes the "default" concept useless
enddocument
produces:
Why? Am I missing something?
Is there a way to get this default behaviour working regardless of previous calls to the macro?
macros key-value xkeyval scoping default
macros key-value xkeyval scoping default
asked Sep 3 at 10:33
iago-lito
610411
610411
3
There is no group inmyCommand
. So the scope of the code inmyCommand
is the same for all invocations in the example. You can add a group yourself withbegingroup
andendgroup
.
â moewe
Sep 3 at 10:38
@moewe Oh, so you mean it is my responsibility to close the scope ofmyCommand
. This works indeed, thanks :) Is an extra pair ofequivalent to
begingroup endgroup
?
â iago-lito
Sep 3 at 10:47
2
remember that this is a macro expansion language not a functional programming language, macro definitions are essentially just expanded inline and there is no scope associated with them.
â David Carlisle
Sep 3 at 11:24
@DavidCarlisle That is true. When we get into concepts like "optional default keyworded arguments", it is easy to tend to forget XD
â iago-lito
Sep 3 at 11:26
2
@iago-lito it's a "uniquely interesting" macro expansion language:-) for your other question if being used for groupingis more or less the same as
begingroupendgroup
unless you are in math mode, butcan be used for more things, eg delimiting arguments that
begingroup
can not be used for, so it depends....
â David Carlisle
Sep 3 at 11:28
 |Â
show 1 more comment
3
There is no group inmyCommand
. So the scope of the code inmyCommand
is the same for all invocations in the example. You can add a group yourself withbegingroup
andendgroup
.
â moewe
Sep 3 at 10:38
@moewe Oh, so you mean it is my responsibility to close the scope ofmyCommand
. This works indeed, thanks :) Is an extra pair ofequivalent to
begingroup endgroup
?
â iago-lito
Sep 3 at 10:47
2
remember that this is a macro expansion language not a functional programming language, macro definitions are essentially just expanded inline and there is no scope associated with them.
â David Carlisle
Sep 3 at 11:24
@DavidCarlisle That is true. When we get into concepts like "optional default keyworded arguments", it is easy to tend to forget XD
â iago-lito
Sep 3 at 11:26
2
@iago-lito it's a "uniquely interesting" macro expansion language:-) for your other question if being used for groupingis more or less the same as
begingroupendgroup
unless you are in math mode, butcan be used for more things, eg delimiting arguments that
begingroup
can not be used for, so it depends....
â David Carlisle
Sep 3 at 11:28
3
3
There is no group in
myCommand
. So the scope of the code in myCommand
is the same for all invocations in the example. You can add a group yourself with begingroup
and endgroup
.â moewe
Sep 3 at 10:38
There is no group in
myCommand
. So the scope of the code in myCommand
is the same for all invocations in the example. You can add a group yourself with begingroup
and endgroup
.â moewe
Sep 3 at 10:38
@moewe Oh, so you mean it is my responsibility to close the scope of
myCommand
. This works indeed, thanks :) Is an extra pair of
equivalent to begingroup endgroup
?â iago-lito
Sep 3 at 10:47
@moewe Oh, so you mean it is my responsibility to close the scope of
myCommand
. This works indeed, thanks :) Is an extra pair of
equivalent to begingroup endgroup
?â iago-lito
Sep 3 at 10:47
2
2
remember that this is a macro expansion language not a functional programming language, macro definitions are essentially just expanded inline and there is no scope associated with them.
â David Carlisle
Sep 3 at 11:24
remember that this is a macro expansion language not a functional programming language, macro definitions are essentially just expanded inline and there is no scope associated with them.
â David Carlisle
Sep 3 at 11:24
@DavidCarlisle That is true. When we get into concepts like "optional default keyworded arguments", it is easy to tend to forget XD
â iago-lito
Sep 3 at 11:26
@DavidCarlisle That is true. When we get into concepts like "optional default keyworded arguments", it is easy to tend to forget XD
â iago-lito
Sep 3 at 11:26
2
2
@iago-lito it's a "uniquely interesting" macro expansion language:-) for your other question if being used for grouping
is more or less the same as begingroupendgroup
unless you are in math mode, but
can be used for more things, eg delimiting arguments that begingroup
can not be used for, so it depends....â David Carlisle
Sep 3 at 11:28
@iago-lito it's a "uniquely interesting" macro expansion language:-) for your other question if being used for grouping
is more or less the same as begingroupendgroup
unless you are in math mode, but
can be used for more things, eg delimiting arguments that begingroup
can not be used for, so it depends....â David Carlisle
Sep 3 at 11:28
 |Â
show 1 more comment
1 Answer
1
active
oldest
votes
up vote
6
down vote
accepted
Macro definitions don't add a level of grouping themselves, so everything you do in the macro code "leaks out" and just happens in the scope the macro is called in. The idea is that calling somemacro
defined with newcommand
is the same as pasting the contents of the code argument at that place (without the surrounding braces).
For example
documentclassarticle
usepackagexcolor
newcommand*mygreen[1]%
colorgreen#1
begindocument
Not green
mygreenthis is green
but so is this...
again black
enddocument
yields two lines of green text because mygreen
does not have scope restrictions that would prevent it from applying to the following line. The last line is outside the scope mygreen
was called in, so it is black again.
The simple solution is to add begingroup...endgroup
to make your settings local to the macro call.
documentclassreport
usepackagexkeyval
% Define a custom command option using `boolkey`
makeatletter
define@boolkeymyCommandoption[true] % one boolean option
newcommandmyCommand[2]%
begingroup
setkeysmyCommand#1%
ifoption%
textbf#2%
else%
#2%
fi%
endgroup
makeatother
begindocument
myCommandnot bold % default behaviour is not to bold
myCommand[option]bold % explicitly set option to bold
myCommandnot bold % fail! default behaviour was expected!
myCommand[option=false]not bold % workaround that makes the "default" concept useless
enddocument
Interesting. So it is my responsibility to close my macro scope. Cheers :)
â iago-lito
Sep 3 at 10:49
2
@iago-lito Pretty much. Although I would say that it would also be your responsibility to open and close a new scope if you want one. The default behaviour just does not change the scope at all.
â moewe
Sep 3 at 10:51
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
6
down vote
accepted
Macro definitions don't add a level of grouping themselves, so everything you do in the macro code "leaks out" and just happens in the scope the macro is called in. The idea is that calling somemacro
defined with newcommand
is the same as pasting the contents of the code argument at that place (without the surrounding braces).
For example
documentclassarticle
usepackagexcolor
newcommand*mygreen[1]%
colorgreen#1
begindocument
Not green
mygreenthis is green
but so is this...
again black
enddocument
yields two lines of green text because mygreen
does not have scope restrictions that would prevent it from applying to the following line. The last line is outside the scope mygreen
was called in, so it is black again.
The simple solution is to add begingroup...endgroup
to make your settings local to the macro call.
documentclassreport
usepackagexkeyval
% Define a custom command option using `boolkey`
makeatletter
define@boolkeymyCommandoption[true] % one boolean option
newcommandmyCommand[2]%
begingroup
setkeysmyCommand#1%
ifoption%
textbf#2%
else%
#2%
fi%
endgroup
makeatother
begindocument
myCommandnot bold % default behaviour is not to bold
myCommand[option]bold % explicitly set option to bold
myCommandnot bold % fail! default behaviour was expected!
myCommand[option=false]not bold % workaround that makes the "default" concept useless
enddocument
Interesting. So it is my responsibility to close my macro scope. Cheers :)
â iago-lito
Sep 3 at 10:49
2
@iago-lito Pretty much. Although I would say that it would also be your responsibility to open and close a new scope if you want one. The default behaviour just does not change the scope at all.
â moewe
Sep 3 at 10:51
add a comment |Â
up vote
6
down vote
accepted
Macro definitions don't add a level of grouping themselves, so everything you do in the macro code "leaks out" and just happens in the scope the macro is called in. The idea is that calling somemacro
defined with newcommand
is the same as pasting the contents of the code argument at that place (without the surrounding braces).
For example
documentclassarticle
usepackagexcolor
newcommand*mygreen[1]%
colorgreen#1
begindocument
Not green
mygreenthis is green
but so is this...
again black
enddocument
yields two lines of green text because mygreen
does not have scope restrictions that would prevent it from applying to the following line. The last line is outside the scope mygreen
was called in, so it is black again.
The simple solution is to add begingroup...endgroup
to make your settings local to the macro call.
documentclassreport
usepackagexkeyval
% Define a custom command option using `boolkey`
makeatletter
define@boolkeymyCommandoption[true] % one boolean option
newcommandmyCommand[2]%
begingroup
setkeysmyCommand#1%
ifoption%
textbf#2%
else%
#2%
fi%
endgroup
makeatother
begindocument
myCommandnot bold % default behaviour is not to bold
myCommand[option]bold % explicitly set option to bold
myCommandnot bold % fail! default behaviour was expected!
myCommand[option=false]not bold % workaround that makes the "default" concept useless
enddocument
Interesting. So it is my responsibility to close my macro scope. Cheers :)
â iago-lito
Sep 3 at 10:49
2
@iago-lito Pretty much. Although I would say that it would also be your responsibility to open and close a new scope if you want one. The default behaviour just does not change the scope at all.
â moewe
Sep 3 at 10:51
add a comment |Â
up vote
6
down vote
accepted
up vote
6
down vote
accepted
Macro definitions don't add a level of grouping themselves, so everything you do in the macro code "leaks out" and just happens in the scope the macro is called in. The idea is that calling somemacro
defined with newcommand
is the same as pasting the contents of the code argument at that place (without the surrounding braces).
For example
documentclassarticle
usepackagexcolor
newcommand*mygreen[1]%
colorgreen#1
begindocument
Not green
mygreenthis is green
but so is this...
again black
enddocument
yields two lines of green text because mygreen
does not have scope restrictions that would prevent it from applying to the following line. The last line is outside the scope mygreen
was called in, so it is black again.
The simple solution is to add begingroup...endgroup
to make your settings local to the macro call.
documentclassreport
usepackagexkeyval
% Define a custom command option using `boolkey`
makeatletter
define@boolkeymyCommandoption[true] % one boolean option
newcommandmyCommand[2]%
begingroup
setkeysmyCommand#1%
ifoption%
textbf#2%
else%
#2%
fi%
endgroup
makeatother
begindocument
myCommandnot bold % default behaviour is not to bold
myCommand[option]bold % explicitly set option to bold
myCommandnot bold % fail! default behaviour was expected!
myCommand[option=false]not bold % workaround that makes the "default" concept useless
enddocument
Macro definitions don't add a level of grouping themselves, so everything you do in the macro code "leaks out" and just happens in the scope the macro is called in. The idea is that calling somemacro
defined with newcommand
is the same as pasting the contents of the code argument at that place (without the surrounding braces).
For example
documentclassarticle
usepackagexcolor
newcommand*mygreen[1]%
colorgreen#1
begindocument
Not green
mygreenthis is green
but so is this...
again black
enddocument
yields two lines of green text because mygreen
does not have scope restrictions that would prevent it from applying to the following line. The last line is outside the scope mygreen
was called in, so it is black again.
The simple solution is to add begingroup...endgroup
to make your settings local to the macro call.
documentclassreport
usepackagexkeyval
% Define a custom command option using `boolkey`
makeatletter
define@boolkeymyCommandoption[true] % one boolean option
newcommandmyCommand[2]%
begingroup
setkeysmyCommand#1%
ifoption%
textbf#2%
else%
#2%
fi%
endgroup
makeatother
begindocument
myCommandnot bold % default behaviour is not to bold
myCommand[option]bold % explicitly set option to bold
myCommandnot bold % fail! default behaviour was expected!
myCommand[option=false]not bold % workaround that makes the "default" concept useless
enddocument
edited Sep 3 at 10:56
answered Sep 3 at 10:48
moewe
76.9k797291
76.9k797291
Interesting. So it is my responsibility to close my macro scope. Cheers :)
â iago-lito
Sep 3 at 10:49
2
@iago-lito Pretty much. Although I would say that it would also be your responsibility to open and close a new scope if you want one. The default behaviour just does not change the scope at all.
â moewe
Sep 3 at 10:51
add a comment |Â
Interesting. So it is my responsibility to close my macro scope. Cheers :)
â iago-lito
Sep 3 at 10:49
2
@iago-lito Pretty much. Although I would say that it would also be your responsibility to open and close a new scope if you want one. The default behaviour just does not change the scope at all.
â moewe
Sep 3 at 10:51
Interesting. So it is my responsibility to close my macro scope. Cheers :)
â iago-lito
Sep 3 at 10:49
Interesting. So it is my responsibility to close my macro scope. Cheers :)
â iago-lito
Sep 3 at 10:49
2
2
@iago-lito Pretty much. Although I would say that it would also be your responsibility to open and close a new scope if you want one. The default behaviour just does not change the scope at all.
â moewe
Sep 3 at 10:51
@iago-lito Pretty much. Although I would say that it would also be your responsibility to open and close a new scope if you want one. The default behaviour just does not change the scope at all.
â moewe
Sep 3 at 10:51
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f449098%2fxkeyval-boolkey-setting-is-persistent-across-macro-calls-scope-leak%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
3
There is no group in
myCommand
. So the scope of the code inmyCommand
is the same for all invocations in the example. You can add a group yourself withbegingroup
andendgroup
.â moewe
Sep 3 at 10:38
@moewe Oh, so you mean it is my responsibility to close the scope of
myCommand
. This works indeed, thanks :) Is an extra pair ofequivalent to
begingroup endgroup
?â iago-lito
Sep 3 at 10:47
2
remember that this is a macro expansion language not a functional programming language, macro definitions are essentially just expanded inline and there is no scope associated with them.
â David Carlisle
Sep 3 at 11:24
@DavidCarlisle That is true. When we get into concepts like "optional default keyworded arguments", it is easy to tend to forget XD
â iago-lito
Sep 3 at 11:26
2
@iago-lito it's a "uniquely interesting" macro expansion language:-) for your other question if being used for grouping
is more or less the same as
begingroupendgroup
unless you are in math mode, butcan be used for more things, eg delimiting arguments that
begingroup
can not be used for, so it depends....â David Carlisle
Sep 3 at 11:28