3

Why would I be getting an error that the control sequence is undefined while I'm trying to define it?

! Undefined control sequence.
<argument> * \cs_set:Nn \obj_this:n 
                                    {\prop_item:Nn \l_tmpa_prop {##1}}\obj_t...
\nonstopmode \input expl3-generic \relax \ExplSyntaxOn % -*- expl3 -*-

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\cs_new:Nn \obj_method:nnn
  {
    \cs_new:cn { #1_#2 }
      {
        \cs_set:Nn \obj_this:n
          { \prop_item:Nn ##1 {####1} }
        #3
      }
  }

\prop_put:Nnn \l_tmpa_prop { key } { value }

\obj_method:nnn { sean } { get:Nn }
  { \obj_this:n {#2} }

\exp_args:No \msg_term:n { \sean_get:Nn \l_tmpa_prop { key } }

\bye

Log

*************************************************
! Undefined control sequence.
<argument> * \cs_set:Nn \obj_this:n 
                                    {\prop_item:Nn \l_tmpa_prop {##1}}\obj_t...

\__iow_wrap_set:Nx #1#2->\cs_set_nopar:Npx #1{#2
                                                }
\iow_wrap:nnnN ...wrap_set:Nx \l__iow_wrap_tl {#1}
                                                  \tl_set:Nx \l__iow_newline...

\msg_term:n ..._wrap:nnnN {* #1}{* }{}\iow_term:n 
                                                  \iow_term:n {*************...
l.20 ...rm:n { \sean_get:Nn \l_tmpa_prop { key } }

! Undefined control sequence.
<argument> ...m:Nn \l_tmpa_prop {##1}}\obj_this:n 
                                                  {key}
\__iow_wrap_set:Nx #1#2->\cs_set_nopar:Npx #1{#2
                                                }
\iow_wrap:nnnN ...wrap_set:Nx \l__iow_wrap_tl {#1}
                                                  \tl_set:Nx \l__iow_newline...

\msg_term:n ..._wrap:nnnN {* #1}{* }{}\iow_term:n 
                                                  \iow_term:n {*************...
l.20 ...rm:n { \sean_get:Nn \l_tmpa_prop { key } }

* \cs_set:Nn {}{key}
*************************************************
3

If you comment out

\exp_args:No \msg_term:n { \sean_get:Nn \l_tmpa_prop { key } }

you'll see that the error isn't from the definition, but from the fact that the argument to \msg_term:n isn't fully expandable. If you change that line to

\exp_args:No \tl_show:n { \sean_get:Nn \l_tmpa_prop { key } }

you get:

> \cs_set:Nn \obj_this:n {\prop_item:Nn \l_tmpa_prop {##1}}\obj_this:n {key}

which is where the error is coming from.

The o-expansion literally means "expand once", and in the context of a multi-token argument it refers only to the first token. In short, it just won't work here :)

If you run simply

\sean_get:Nn \l_tmpa_prop { key }

it will indeed typeset value, but you can't directly access that without doing more assignment in your code; something like:

\cs_new:Nn \obj_method:nnn
  {
    \cs_new:cn { #1_#2 }
      {
        \cs_set:Nn \obj_this:n
          { \prop_get:NnN ##1 {####1} ##3 }
        #3
      }
  }

\prop_put:Nnn \l_tmpa_prop { key } { value }
\obj_method:nnn { sean } { get:NnN } { \obj_this:n {#2} }

\sean_get:NnN \l_tmpa_prop { key } \l_tmpa_tl
\tl_show:N \l_tmpa_tl

But I have no idea if that makes any sense for your intended application!

| improve this answer | |
  • Was just writing much the same. You get a LaTeX3 error if you make the set up properly protected and remove the spurious \exp_args:No leaving the rest of that line intact. – Joseph Wright Jul 7 '15 at 5:46
  • 1
    The 'intended application' is a bit wordy for this site, but this works for me! Thanks! – Sean Allred Jul 7 '15 at 11:30

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.