# How can I avoid the need for global variables here?

Consider the following example:

\documentclass{article}
\usepackage{xparse}
\usepackage{longtable}
\usepackage{multirow}
\usepackage{hyperref}

\ExplSyntaxOn

\int_new:N \g__ioiooiioio_args_int

\NewDocumentCommand{\mymacro}{ m m m } % So the solution should have { m m m }
{
\ioiooiioio_setargs:nnn { #1 } { #2 } { #3 }
\ioiooiioio_print:
}

\seq_new:N \l__ioiooiioio_first_col_seq
\seq_new:N \l__ioiooiioio_second_col_seq
\tl_new:N \l__ioiooiioio_table_body_tl
\int_new:N \l__ioiooiioio_step_int

\cs_new_protected:Npn \ioiooiioio_setargs:nnn #1 #2 #3
{
\seq_set_split:Nnn \l__ioiooiioio_first_col_seq { , } { #1 }
\seq_set_split:Nnn \l__ioiooiioio_second_col_seq { , } { #2 }
\tl_clear:N \l__ioiooiioio_table_body_tl
\int_zero:N \l__ioiooiioio_step_int
\int_gzero:N \g__ioiooiioio_args_int
\int_gset:Nn \g__ioiooiioio_args_int { \seq_count:N \l__ioiooiioio_first_col_seq }
\l__ioiooiioio_first_col_seq
\l__ioiooiioio_second_col_seq
\__ioiooiioio_fill_body:nn
}

\cs_new_protected:Npn \__ioiooiioio_fill_body:nn #1 #2
{
\int_incr:N \l__ioiooiioio_step_int
\tl_put_right:Nn \l__ioiooiioio_table_body_tl { & #1 & #2 & }
\int_compare:nT { \l__ioiooiioio_step_int = 1}
{
\tl_put_right:Nn \l__ioiooiioio_table_body_tl
{
\multirow{ \g__ioiooiioio_args_int }{*}{
\hyperlink { doc.rc.\g_ioiooiioio_link_name } { $\rightarrow$ }
}
}
}
\int_compare:nTF { \l__ioiooiioio_step_int = \g__ioiooiioio_args_int}
{
\tl_put_right:Nn \l__ioiooiioio_table_body_tl
{ \\ }
}
{
\tl_put_right:Nn \l__ioiooiioio_table_body_tl
{ \\* }
}
}

\cs_new_protected:Npn \ioiooiioio_print:
{
\multirow{ \g__ioiooiioio_args_int }{*}{ \seq_item:Nn \l__ioiooiioio_first_col_seq { 1 } } \l__ioiooiioio_table_body_tl
}
\ExplSyntaxOff

\begin{document}
\begin{longtable}{cccc}
\mymacro{this is a test,this,is a,test}{now its,not a,test,anymore}{stuff}
\\ % for space, not relevant to the question
\\ % for space, not relevant to the question
\multirow{4}{*}{this is a test}     & this is a test    & now its   & \multirow{4}{*}{\hyperlink{doc.rc.stuff}{$\rightarrow$}} \\*
& this          & not a     & \\*
& is a          & test      & \\*
& test          & anymore   & \\

\end{longtable}
\end{document}


My macro mimics the part of the table below it exactly. But I don't want to use all these globals (they're ugly). How can I achieve the same effect without the need for globals?

• You edit your questions… more than “recommended”. I know that many times your perspective towards the question change, and you solve it partially, or you discover something you didn't know when you wrote it at first time. But this case is different, here the question changes too much. I think you should refine your question more before posting it here. – Manuel May 30 '14 at 19:59
• @Manuel I'm aware. Sorry. Trying to not spam the front page with endless new questions (I'm already doing it too much). Also, this case is more demarcated and/or relevant to understanding of a somewhat more revolutionary take on LaTeX coding (in my opinion), which was my primary reason for altering an existing question. – 1010011010 May 30 '14 at 20:04

I agree with the majority that the way you've been framing your questions hasn't been helpful. Still, here goes: you don't need global variables, just some care about when things get expanded—and expansion control is one of the great strengths of expl3.

The mistake in your latest code was the same as in the previous iteration: you were expanding inside a cell, not at the point where the table body was composed. This can be fixed, as you did, by setting the variables globally, but you can also just expand them at the right time with judicious use of \tl_put_right:Nx, \int_use:N, and \exp_not:N. What you want is

\int_compare:nT { \l__ioiooiioio_step_int = \c_one }
{
\tl_put_right:Nx \l__ioiooiioio_table_body_tl
{
\exp_not:N \multirow { \int_use:N \l__ioiooiioio_args_int } { * }
{
{ $\rightarrow$ }

Then you can change all your global settings into local ones. And if you're unsure about what actually went into the body, do a \tl_show:N at strategic points. This will let you see whether you've inserted a variable or its value (which is what you want).
Also, remember to give the variable names the correct suffix based on their type: it should be \l__ioiooiioio_link_name_tl instead of \l__ioiooiioio_link_name, because it's a token list variable.