我正在尝试调试expl3
使用l3seq
和的代码seq_gput_right
。通过添加enable-debug
并检查代码,我得到了错误:
! LaTeX3 Error: Inconsistent local / global assignment
之前是隐藏的(但运行良好)。错误来自行\seq_gput_right:cn
,但如果我将其更改为,\seq_put_right:cn
错误会消失,但代码无法正常工作。
示例文件如下,我已经使用过很多次了,但没有注意到错误。
\documentclass{article}
\RequirePackage[enable-debug]{expl3}
\usepackage{xparse}
\ExplSyntaxOn
\debug_on:n{check-declarations,deprecation,check-expressions}
% internal
\NewDocumentCommand{\_appendcontents}{ m +m }
{
\mymodule_append_contents:nn { #1 } {{ #2 }}
}
% external
\NewExpandableDocumentCommand{\usecontents}{O{1}m}
{
\mymodule_use_contents:nn { #1 } { #2 }
}
\cs_new_protected:Npn \mymodule_append_contents:nn #1 #2
{
\seq_if_exist:cF { l_mymodule_contents_#1_seq }
{ \seq_new:c { l_mymodule_contents_#1_seq } }
\__mymodule_append_contents:nn { #1 } { #2 }
}
\cs_new_protected:Npn \__mymodule_append_contents:nn #1 #2
{
\tl_map_inline:nn { #2 }
{
%\seq_put_right:cn { l_mymodule_contents_#1_seq } { ##1 }
\seq_gput_right:cn { l_mymodule_contents_#1_seq } { ##1 }
}
}
\cs_new:Npn \mymodule_use_contents:nn #1 #2
{
\seq_item:cn { l_mymodule_contents_#2_seq } { #1 }
}
% [key=val]
\keys_define:nn { mymodule }
{
save-cmd .tl_set:N = \l_mymodule_cmd_save_tl,
save-cmd .initial:n = contents,
show-cmd .bool_set:N = \l_mymodule_cmd_show_tl,
show-cmd .initial:n = false,
}
% \Scontents[...]{...}
\NewDocumentCommand{\Scontents}{ o +m }
{
\group_begin:
\IfNoValueF { #1 } { \keys_set:nn { mymodule } { #1 } }
\_appendcontents{\l_mymodule_cmd_save_tl}{ #2 } % add to list
\IfBooleanT { \l_mymodule_cmd_show_tl } { \usecontents[-1]{ \l_mymodule_cmd_save_tl} }
\group_end:
}
\ExplSyntaxOff
\begin{document}
\section{Default list}
Use command \par
\Scontents{saved in list \{contents\} index 1}\par
\Scontents{saved in list \{contents\} index 2}
Show saved\par
\usecontents[2]{contents}\par
\usecontents[1]{contents}
\section{Custom list}
Use command \par
\Scontents[save-cmd=test-cmd]{saved in list \{test-cmd\} index 1}
\Scontents[save-cmd=test-cmd]{saved in list \{test-cmd\} index 2}
\Scontents[save-cmd=test-cmd]{saved in list \{test-cmd\} index 3}
Show saved in list \{test-cmd\}\par
\usecontents[3]{test-cmd}\par
\usecontents[1]{test-cmd}\par
\usecontents[2]{test-cmd}\par
Add one more to list \{contents\}\par
\Scontents{saved in list \{contents\} index 3}
Show saved in list \{contents\}\par
\usecontents[3]{contents}\par
\usecontents[2]{contents}\par
\usecontents[1]{contents}
\end{document}
我该如何解决?
问候语
答案1
主要问题是对局部变量进行全局赋值。
变量名称以\l_
for 开头当地的对于\g_
全球的您应该使用全局变量\seq_gput_right:Nn
(或其变体)。
布尔变量的名称以_bool
, 而不是结尾_tl
。
此外,用 定义的命令\NewDocumentCommand
不应包含_
其中。
另一个问题:你正在进行无意义的\tl_map_inline:nn
循环。
\documentclass{article}
\usepackage[enable-debug]{expl3}
\usepackage{xparse}
\ExplSyntaxOn
\debug_on:n{check-declarations,deprecation,check-expressions}
% external
\NewExpandableDocumentCommand{\usecontents}{O{1}m}
{
\mymodule_use_contents:nn { #1 } { #2 }
}
% \Scontents[...]{...}
\NewDocumentCommand{\Scontents}{ O{} +m }
{
\group_begin:
\keys_set:nn { mymodule } { #1 }
\mymodule_append_contents:nn { \l_mymodule_cmd_save_tl } { #2 } % add to list
\bool_if:NT \l_mymodule_cmd_show_bool
{ \mymodule_use_contents:nn { -1 } { \l_mymodule_cmd_save_tl } }
\group_end:
}
% internal
\cs_new_protected:Npn \mymodule_append_contents:nn #1 #2
{
\seq_if_exist:cF { g_mymodule_contents_#1_seq }
{ \seq_new:c { g_mymodule_contents_#1_seq } }
\seq_gput_right:cn { g_mymodule_contents_#1_seq } { #2 }
}
\cs_new:Npn \mymodule_use_contents:nn #1 #2
{
\seq_item:cn { g_mymodule_contents_#2_seq } { #1 }
}
% [key=val]
\keys_define:nn { mymodule }
{
save-cmd .tl_set:N = \l_mymodule_cmd_save_tl,
save-cmd .initial:n = contents,
show-cmd .bool_set:N = \l_mymodule_cmd_show_bool,
show-cmd .default:n = true,
show-cmd .initial:n = false,
}
\ExplSyntaxOff
\begin{document}
\section{Default list}
Use command \par
\Scontents{saved in list \{contents\} index 1}\par
\Scontents{saved in list \{contents\} index 2}
Show saved\par
\usecontents[2]{contents}\par
\usecontents[1]{contents}
\section{Custom list}
Use command \par
\Scontents[save-cmd=test-cmd]{saved in list \{test-cmd\} index 1}
\Scontents[save-cmd=test-cmd]{saved in list \{test-cmd\} index 2}
\Scontents[save-cmd=test-cmd]{saved in list \{test-cmd\} index 3}
Show saved in list \{test-cmd\}\par
\usecontents[3]{test-cmd}\par
\usecontents[1]{test-cmd}\par
\usecontents[2]{test-cmd}\par
Add one more to list \{contents\}\par
\Scontents{saved in list \{contents\} index 3}
Show saved in list \{contents\}\par
\usecontents[3]{contents}\par
\usecontents[2]{contents}\par
\usecontents[1]{contents}
\end{document}