# Testing whether a name is defined after building up the name

I'd like to test whether \solflag is defined or whether \profflag is defined. I'd like to do so with a macro whose argument could be either "sol" or "prof" (or some other word).

My "minimal (non)working example" attempt at this is

\documentclass{article}
\RequirePackage{ifthen}
\newcommand{\solflag}{}
\newcommand{\mytest}[1]
{\ifthenelse{\isundefined{\#1flag}} {UNDEFINED}{DEFINED}}

\begin{document}

Sol test: \mytest{sol}

Bar test: \mytest{bar}

2nd bar test: \ifthenelse{\isundefined{\barflag}} {UNDEFINED}{DEFINED}

\end{document}


The result, however, is this:

Sol test: DEFINED
Bar test: DEFINED
2nd bar test: UNDEFINED


My guess is that the first "Bar" test is checking whether \bar is defined, i.e., that the concatenation of \#1 and flag in the macro just isn't happening or something.

I suspect that the answer I need is somewhere in the LaTeX-Fu of this answer, but I simply cannot make head or tail of that.

Is it possible to do what I'm hoping to do?

• your \mytest douesn't use #1 at all so it does not use its argument – David Carlisle Sep 23 '16 at 19:16
• @DavidCarlisle He actually does use #1, but with the improper syntax \#1flag. To the OP, the proper way to convey \#1flag is \csname #1flag\endcsname. The sequence \#1flag gets expanded as #1flag where # is literally the pound sign. – Steven B. Segletes Sep 23 '16 at 19:28
• @StevenB.Segletes no, that was my point #1 would be a reference to an argument \# is an instruction to typeset a # (a pound sign is £ :-) it does not expand to a # (it doesn't expand at all actually, it's a chardef token) – David Carlisle Sep 23 '16 at 20:11
• cryptic is good sometimes:-) – David Carlisle Sep 23 '16 at 20:18
• I'd like to thank all the folks who answered; each answer taught me something new. (And @DavidCarlisle's comment taught me to beware of his answer, because they might be more subtle than they seem...) – John Sep 23 '16 at 21:23

The etoolbox package has a lot of good stuff in it for these and other low level things.

\documentclass{article}
\RequirePackage{etoolbox}
\newcommand{\solflag}{}
\newcommand{\mytest}[1]{\ifcsdef{#1flag}{DEFINED}{UNDEFINED}}
\begin{document}
Sol test: \mytest{sol}

Bar test: \mytest{bar}
\end{document}


Other similar tests provided by the package include \ifdef, \ifundef, \ifcsundef, \ifdefmacro, \ifcsmacro and many more.

When you write

\#1flag


you have six tokens

\# • 1 • f • l • a • g


(I use • for separating tokens by ease of reading). You may be better served with

\documentclass{article}
\usepackage{ifthen}
\newcommand{\solflag}{}
\newcommand{\mytest}[1]{%
\ifthenelse{\expandafter\isundefined\expandafter{\csname #1flag\endcsname}}
{UNDEFINED}{DEFINED}%
}

\begin{document}

Sol test: \mytest{sol}

Bar test: \mytest{bar}

2nd bar test: \ifthenelse{\isundefined{\barflag}} {UNDEFINED}{DEFINED}

\end{document}


that prepares the token \barflag before being evaluated by \ifthenelse.

The LaTeX kernel has already a macro for this:

\documentclass{article}
\usepackage{ifthen}
\newcommand{\solflag}{}

\makeatletter
\newcommand{\mytest}[1]{%
\@ifundefined{#1flag}{UNDEFINED}{DEFINED}%
}
\makeatother

\begin{document}

Sol test: \mytest{sol}

Bar test: \mytest{bar}

2nd bar test: \ifthenelse{\isundefined{\barflag}} {UNDEFINED}{DEFINED}

\end{document}


However, this has the consequence that the following test based on \isundefined returns true.

If you plan to use both kinds of test, use

\documentclass{article}
\usepackage{ifthen}
\newcommand{\solflag}{}
\makeatletter
\newcommand{\mytest}[1]{%
\begingroup
\@ifundefined{#1flag}{\endgroup\@firstoftwo}{\endgroup\@secondoftwo}%
{UNDEFINED}%
{DEFINED}%
}
\makeatother

\begin{document}

Sol test: \mytest{sol}

Bar test: \mytest{bar}

2nd bar test: \ifthenelse{\isundefined{\barflag}} {UNDEFINED}{DEFINED}

\end{document}


On a modern TeX system, LaTeX uses e-TeX, so you can do

\newcommand{\mytest}[1]{%
\ifcsname #1flag\endcsname
DEFINED%
\else
UNDEFINED%
\fi
}


I wouldn't use ifthen for this, but if you do then you need to use #1 to construct the csname to test. Note \# is a command to produce # it is not a reference to an argument, so your definition does not use its argument at all.

\documentclass{article}

\usepackage{ifthen}

\newcommand{\solflag}{}
\newcommand{\mytest}[1]{%
\ifthenelse{\expandafter\isundefined\csname#1flag\endcsname}{UNDEFINED}{DEFINED}}

\begin{document}

Sol test: \mytest{sol}

Bar test: \mytest{bar}

2nd bar test: \ifthenelse{\isundefined{\barflag}} {UNDEFINED}{DEFINED}

\end{document}