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}
*************************************************

1 Answer 1

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!

2
  • 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, 2015 at 5:46
  • 1
    The 'intended application' is a bit wordy for this site, but this works for me! Thanks! Jul 7, 2015 at 11:30

You must log in to answer this question.

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