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'
  • 2
    Why don't you use etoolbox, that might make your code easier to deal with – daleif Jan 28 '14 at 23:10
  • In my experiment the last line prints val2. But I added % to protect end of lines. – egreg Jan 28 '14 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. – Sean Allred Jan 29 '14 at 6:46
  • @SeanAllred. Yes, it is actually just a bit of deliberate practice, but I'll take a look at your suggestions. Thanks. – Miek Messerschmidt Jan 29 '14 at 9:24
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

| improve this answer | |
  • Thanks egreg. I just realized its because of the white space/unprotected lines. – Miek Messerschmidt Jan 28 '14 at 23:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.