# Custom variables defined in preamble

I am trying to define some variables in the preamble so they are initialized there and then printed in the text body. Here is what I tried

\documentclass[a4paper,11pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[frenchb]{babel}

\newcommand{\cost}[1]{\def\@cost{#1}}
\newcommand{\refArticle}[1]{\def\@refArticle{#1}}

\cost{400}
\refArticle{TOTO01}

\begin{document}

This is a non-working test; it will cost \@cost dollars to buy \@refArticle.

\end{document}


It did not work. I got an error

! Use of \@ doesn't match its definition.


Which buggers me, since

\documentclass[a4paper,11pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[frenchb]{babel}

\newcommand{\cost}[1]{\def\@cost{#1}}
\newcommand{\refArticle}[1]{\def\@refArticle{#1}}

\cost{400}
% \refArticle{TOTO01}

\begin{document}

This is a working test; it will cost \@cost to buy what you want.

\end{document}


works.

I probably missed something with variable definitions. Have you any idea of what can be wrong with my approach?

-

the form of the variable \@cost is "internal", where @ has been defined as a letter.

in the body of your document, @ is defined as "other", and the command \@ has a quite different meaning, incompatible with what you are trying to do.

what you might do instead is this:

\makeatletter
\newcommand{\@cost}[1]{\def\cost{#1}}
\@cost{400}
\makeatother

\begin{document}

This is a working test; it will cost \cost\ to buy what you want.


notice also the "slash-space" following \cost. this (or another space-preserving mechanism) is needed to keep the cost value from running into "to".

edit: take notice of david carlisle's comment -- in this case, it's really better to avoid the use of @ entirely for these commands; both are susceptible to being used in the body of the document, where you really want to avoid @ except for a very few predefined situations. (see any good latex manual for this information.)

-
I tried it the other way round (still with \makeat[...] but inverting \var and \@var) but it didn't work, I did not think of doing it like that, thanks! – MBR Sep 17 '13 at 14:33
@MBR what barbara says is technically correct but highlights that in this usage both the declaration command and the variable itself are intended for document use so shouldn't have an @ in their name, then the makeat... issue would not arise. – David Carlisle Sep 17 '13 at 14:40
+1 for the edit:-) – David Carlisle Sep 17 '13 at 15:33