I've got some macros that I want to set up in my preamble. The problem is that they need to know what the width of a typical line of text will be in the document.
If I do something like,
%% Everything set up correctly
\documentclass{article}
\usepackage[margin=1in,showframe]{geometry}
\setlength{\parindent}{0pt}
\newlength{\testlength}
\setlength{\testlength}{\textwidth}
\newcommand{\myrule}{\rule{\testlength}{4pt}}
\usepackage{lipsum}
\begin{document}
\myrule
\lipsum[1-10]
\end{document}
Then \myrule has the correct width.
But if I do something like
%% FAIL
\documentclass{article}
\usepackage[margin=1in,showframe,twocolumn]{geometry}
\setlength{\parindent}{0pt}
\newlength{\testlength}
\setlength{\testlength}{\textwidth}
\newcommand{\myrule}{\rule{\testlength}{4pt}}
\usepackage{lipsum}
\begin{document}
\myrule
\lipsum[1-10]
\end{document}
I don't get the desired result.
I might be inclined to set the width of my macro as
\setlength{\testlength}{\linewidth}
or
\setlength{\testlength}{\columnwidth}
But both of these fail to get the correct length (apart from the fact that \linewidth, as I understand it, shouldn't really make too much sense in the preamble).
How can my macro know from within the preamble what the proper textwidth should be?
I should note that I'm not particularly concerned about what happens if, let's say, the macro is called from within a multicols environment from the multicol package. In other words, the macro should have an absolute length, not a length relative to a particular environment.

\textwidthis correct in both cases; it isn’t different after all (see Difference between\textwidth,\linewidthand\hsize). If you want to use\linewidthor\columnwidththough, you may use\AtBeginDocument{\setlength{\testlength}{\linewidth}}. – Qrrbrbirlbel Oct 04 '13 at 02:11\textwidth, why not just use it rather than use\testlength? – Werner Oct 04 '13 at 02:14\AtBeginDocumentalmost seems to do the trick. I've got to think through my real document to see where that approach will create what I want. – A.Ellett Oct 04 '13 at 04:36\textwidthto set up other values. But, in the preamble\textwidthis not necessary correctly set yet. Your suggestion works if I rethink how and when I set things through a call to\AtBeginDocument. Though it would be ideal if I didn't have to do that. – A.Ellett Oct 04 '13 at 04:42\@begindocumenthookis "First In, First Out", so if you delay\AtBeginDocument{\setlength{\testlength}{\columnwidth}}just before\begin{document}you shouldn't have any problem, because at that point the page parameters will have been set. Ifetoolboxis loaded, some package could exploit\AtEndPreamble, so just do it yourself too and put the declaration above in\AtEndPreamble. But, as Werner says, why don't you simply use\columnwidth? – egreg Oct 04 '13 at 21:03\columnwidthinto the macro and thus was using an intermediary length to set some basic structural dimensions. Perhaps you or Qrrbrbirlbel could post your comments as answers since they do resolve the matter as it currently stands. – A.Ellett Oct 04 '13 at 21:59