5

With the following I tried to implement a naive dictionary data structure. All works fine, except when trying to nest two such dictionaries. In the last line in the following code the result is "key2", when "val2" is expected.

I'm obviously missing something in how "\returnvalue.get" is expanded. Any thoughts will be appreciated.

\def\newdict #1{

  \expandafter\edef\csname #1 \endcsname{#1} 


  \expandafter\def\csname #1.set \endcsname##1##2{
    \expandafter\def\csname #1.##1\endcsname{##2}
  }


  \expandafter\def\csname #1.get \endcsname##1{
    \csname #1.##1\endcsname
  }


}

\newdict{dict1}
\newdict{dict2}

\csname dict1.set \endcsname{key1}{val1}
\csname dict1.get \endcsname{key1}        %prints 'val1'

\csname dict2.set \endcsname{key2}{val2}
\csname dict2.get \endcsname{key2}        %prints 'val2'

\csname dict1.set \endcsname{key3}{dict2}
\csname dict1.get \endcsname{key3}        %prints 'dict2'

\def\proxyname{dict2}
\csname \proxyname.set \endcsname{key4}{val4}
\csname dict2.get \endcsname{key4}              %prints 'val4'
\csname \proxyname.get \endcsname{key2}         %prints 'val2'

\edef\returnvalue{\csname dict1.get \endcsname{key3}}
\returnvalue                              %prints 'dict2'

\csname \returnvalue.get \endcsname{key2} %prints 'key2'
4
  • 2
    Why don't you use etoolbox, that might make your code easier to deal with
    – daleif
    Commented Jan 28, 2014 at 23:10
  • In my experiment the last line prints val2. But I added % to protect end of lines.
    – egreg
    Commented Jan 28, 2014 at 23:13
  • 1
    Unless this is for a 'can I do it' project, look up l3prop via texdoc interface3. You can easily write a document interface with xparse. I would personally avoid using `etoolbox if possible, I understand much of its functionality is being superseded by the LaTeX3 project. Commented Jan 29, 2014 at 6:46
  • @SeanAllred. Yes, it is actually just a bit of deliberate practice, but I'll take a look at your suggestions. Thanks. Commented Jan 29, 2014 at 9:24

1 Answer 1

7

You have several unprotected end of lines, which count as spaces. Some of those I added are not really relevant, but it's good practice to add them.

\def\newdict #1{%
  \expandafter\edef\csname #1 \endcsname{#1}%
  \expandafter\def\csname #1.set \endcsname##1##2{% <-- Important
    \expandafter\def\csname #1.##1\endcsname{##2}%
  }%
  \expandafter\def\csname #1.get \endcsname##1{% <-- Important
    \csname #1.##1\endcsname
  }%
}

\newdict{dict1}
\newdict{dict2}

\csname dict1.set \endcsname{key1}{val1}
\csname dict1.get \endcsname{key1}        %prints 'val1'

\csname dict2.set \endcsname{key2}{val2}
\csname dict2.get \endcsname{key2}        %prints 'val2'

\csname dict1.set \endcsname{key3}{dict2}
\csname dict1.get \endcsname{key3}        %prints 'dict2'

\def\proxyname{dict2}
\csname \proxyname.set \endcsname{key4}{val4}
\csname dict2.get \endcsname{key4}              %prints 'val4'
\csname \proxyname.get \endcsname{key2}         %prints 'val2'

\edef\returnvalue{\csname dict1.get \endcsname{key3}}
\returnvalue                              %prints 'dict2'

\csname \returnvalue.get \endcsname{key2} %prints 'val2'

\bye

enter image description here

1
  • Thanks egreg. I just realized its because of the white space/unprotected lines. Commented Jan 28, 2014 at 23:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .