I'm writing a class for handling multi-language jargon formulas. My idea is to use l3prop to store, for each formula, its language variations -- i.e., a sort of hash table. Building on one of the suggestions in What is the recommended way to assign a value to a variable and retrieve it for later use?, I'm trying the following:
\documentclass{article}
\usepackage{expl3}
\usepackage{etoolbox}
\usepackage{xstring}
\ExplSyntaxOn
\newcommand*{\setproperty}[3][standard]{%
\cs_if_exist:cF { g_citr_#1_prop } { \prop_new:c { g_citr_#1_prop } }
\prop_gput:cnn { g_citr_#1_prop } { #2 } { #3 }
}
\newcommand*{\getproperty}[2][standard]{%
\cs_if_exist:cTF { g_citr_#1_prop } {%
\prop_get:cnN { g_citr_#1_prop } { #2 } \l_citr_value_tl
\quark_if_no_value:NTF \l_citr_value_tl {%
Inexistent~property~`#2'
}{%
\tl_use:N \l_citr_value_tl
}
}{%
Inexistent~family~`#1'
}
}
\prop_new:N \g_citr_standard_prop
\tl_new:N \l_citr_value_tl
\ExplSyntaxOff
\newcommand*{\setformulas}{
\renewcommand*{\do}[1]{%
% split the tuple <f/x/y>
\StrBefore {##1}{/} [\f]
\StrBetween[1,2]{##1}{/}{/}[\x]
\StrBehind [2] {##1}{/} [\y]
% set it
\setproperty[\f]{X}{\x}
\setproperty[\f]{Y}{\y}
% this shows properties are correctly set, but...
`\f::X' = \getproperty[\f]{X}\par
`\f::Y' = \getproperty[\f]{Y}\par
}
\docsvlist{foo/xfoo/yfoo,bar/xbar/ybar}
}
\newcommand*{\dumpformulas}{
\renewcommand*{\do}[1]{%
`##1::X' = \getproperty[##1]{X}\par
`##1::Y' = \getproperty[##1]{Y}\par
}
\docsvlist{foo,bar}
}
\begin{document}
Setting formulas:\par
\setformulas
Getting formulas:\par
\dumpformulas
\end{document}
My problem is that properties that seem to be correctly stored via command \setformulas (there, the calls to \getproperty are for debugging purpose), appear to be mangled when accessed later via (debug) command \dumpformulas. This is what I get:
Setting formulas:
‘foo::X’ = xfoo
‘foo::Y’ = yfoo
‘bar::X’ = xbar
‘bar::Y’ = ybar
Getting formulas:
‘foo::X’ = xbar
‘foo::Y’ = ybar
‘bar::X’ = xbar
‘bar::Y’ = ybar
As you can see, it looks like the 'foo' prop gets overwritten by 'bar' prop, even though the log says that two different props are actually used (or at least that's my interpretation):
\g_citr_foo_prop=\toks35
\g_citr_bar_prop=\toks36
Conversely, using \set/getproperty outside \docsvlist loops works perfectly.
What am I doing wrong?
P.S. I originally tried with a pgffor \foreach loop which would give more concise code, especially avoiding the xstring trickery in \setformulas, but stumbled upon expansion troubles...

\setformulas, the debug print works because\getpropertygives back an\xwhich is then expanded to its original content, right? BTW, I'd appreciate if you could post your complete expl3 solution, since the modified version looks a bit confusing (indeed, everything will go into a class, without the extra\getpropertycalls...) – sphakka Jun 10 '12 at 15:37\x: tracking when things expand is important. (This is a classic problem when following the flow: things like writing to the log or typesetting fully expand everything.) – Joseph Wright Jun 10 '12 at 16:41