“Resettable” variables

I want to define macros within a personal package for a few variables (I don't even know if I should be calling them "variables") that may or may not be defined by the user. My approach so far is this:

\newcommand\@varname{}
\newcommand\printvarname{%
\ifthenelse{\equal{\@varname}{}}{}{\@varname}}


The first command defines an empty \@<varname>; the second command provides a user level \<varname> that set \@<varname> to the value determined by the user; and the third command checks if \@<varname> is been defined by the user, and if so, prints it.

Since I have a lot of those "variables" to set, can I have a \NewResettableCommand{<varname>} (whose argument probably need to be set without the \) that does all of the above?

BTW: I used \newcommand (instead of \providecommand) because I'm running tests in a .tex file before create the packages.

-

This is it:

\newcommand{\NewResettableCommand}[1]{%
\expandafter\newcommand\csname @#1\endcsname{}
\expandafter\newcommand\csname #1\endcsname[1]{%
\expandafter\renewcommand\csname @#1\endcsname{##1}}
\expandafter\newcommand\csname print#1\endcsname{%
\ifthenelse{\equal{\csname @#1\endcsname}{}}{}{\csname @#1\endcsname}}
}

\NewResettableCommand{varname}


Just do all the same operations with #1 in place of the name.

However, it's unclear why the "emptyness" test: if the contents is empty, expanding \@varname will do nothing the same.

However, using \renewcommand for redefining \@varname is just too much: you want to redefine it, so you don't care if it's already defined or not:

\makeatletter % not when the code is in a package
\newcommand{\NewResettableCommand}[1]{%
\expandafter\newcommand\csname #1\endcsname[1]{\@namedef{@#1}{##1}}
\@namedef{@#1}{}
\expandafter\newcommand\csname print#1\endcsname{%
\ifthenelse{\equal{\csname @#1\endcsname}{}}{}{\csname @#1\endcsname}}
}
\makeatother % not when the code is in a package


The compulsory LaTeX3 version:

\RequirePackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\NewResettableCommand}{ m }
{
\tl_new:c { l_nrc_#1_tl }
\cs_new:cpn { #1 } ##1 { \tl_set:cn { l_nrc_#1_tl } { ##1 } }
\cs_new:cpn { print #1 }
{
\tl_if_empty:cF { l_nrc_#1_tl } { \tl_use:c { l_nrc_#1_tl } }
}
}
\ExplSyntaxOff


Note that here nrc is just an arbitrary prefix that you can change at will (maybe uniformizing it to the prefix you're using for your package).

-

You can use the benefits of the package etoolbox to avoid handling with expandafter:

\documentclass{article}
\usepackage{etoolbox}
\newrobustcmd*\NewResettableCommand[1]{%
\ifcsundef{#1}
{%
\csdef{#1}##1{\csdef{@#1}{##1}}%
\csdef{print#1}{%
\ifcsempty{@#1}%
{\typeout{****#1 is empty****}}%
{\csuse{@#1}}%
}%
}
{\typeout{****#1 is defined****}}%
}
\makeatother

\begin{document}
\NewResettableCommand{varname}

\varname{henrique}\printvarname

\varname{}\printvarname
\end{document}

-
You make expandafter sound like a disease;) –  Yiannis Lazarides Mar 9 '12 at 18:44
@YiannisLazarides: It is ;-) This based on expl3 which is more comfortable ;-) –  Marco Daniel Mar 9 '12 at 18:46
Expandafters and futurelets Gave me trouble for a very long time:) –  Yiannis Lazarides Mar 9 '12 at 18:49
@YiannisLazarides: just now futurlet is mysterious for me ;-) –  Marco Daniel Mar 9 '12 at 18:52