Infix form of PutAppend ( >>> ) does not work with variable

I'm new to Mathematica, so I suspect this question involves either a misunderstanding involving variables or the usage of >>>.

On a webMathematica page (backed by Mathematica 5.2), I have the following:

foo[arg_] := Module[{argN},
ArgN = arg;
filenameS ="Absolute/Path/To/File";
ArgN >>> filenameS; (*Problem Line*)
];
foo["test"];


Running this appears to do nothing. When I replace the line

ArgN >>> filenameS;


with

PutAppend[ArgN, filenameS];


It works perfectly, appending "test" to the file. Why doesn't the infix form of PutAppend work in the same way?

-
Also, ArgN >> "Absolute/Path/To/File" works. Puzzling. –  cormullion Aug 15 '13 at 8:17

I believe it does work, just not how you expect. :-)

From the documentation for PutAppend:

Note that there are no quotation marks around filename in the first line.
It is not made particularly clear but you can use this syntax with >>>:

Range[10] >>> file.txt


Which outputs to a file named file.txt directly. This is a special and unusual parsing, used also for >> (Put) and << (Get).

Because of this your results are being sent to a file named filenameS rather than one named according to the string value of filenameS.

Usually file.txt would be interpreted as Dot[file, txt], but in the case of >>> it is parsed differently. Here is a low-level look at what is going on. parseString parses as string using the Front End into Box form.

parseString[s_String, prep : (True | False) : True] :=
FrontEndExecute @ FrontEndUndocumentedTestFEParserPacket[s, prep]

"data >>> file.txt" // parseString
"data :> file.txt"  // parseString

{BoxData[RowBox[{"data", ">>>", "file.txt"}]], StandardForm}

{BoxData[RowBox[{"data", ":>", RowBox[{"file", ".", "txt"}]}]], StandardForm}


Note the different handling. Here RuleDelayed was used as an arbitrary "normal" operator.

As further illustration of the special parsing we can demonstrate that neither Function nor With can effect the substitution. This outputs to a file named x rather than myfile.txt:

With[{x = "myfile.txt"},
Range[5] >>> x
]


This isn't even valid input:

(Range[5] >>> #) &["myfile.txt"]


Syntax::sntxf: "(" cannot be followed by "Range[5]>>>#)".

Syntax::tsntxi: "Range[5]>>>#" is incomplete; more input is needed.

Nevertheless we can attempt to override the behavior with \$PreRead or MakeExpression which work at the Box level:

MakeExpression[RowBox[{lhs_, ">>>", rhs_String}], form_] :=
MakeExpression[
RowBox[{"PutAppend", "[", RowBox[{lhs, ",", rhs}], "]"}],
form
] /; ! StringMatchQ[rhs, "\"*\""]


Now any appearance of lhs >>> rhs where rhs is not a string should behave as PutAppend[lhs, rhs], assuming I wrote the rule correctly.

-
You can use pathnames if the 'filename' is in quotes: Range[100] >>> "/tmp/wizard.txt"... So there's no way to pass a file or pathname into this >>> syntax? –  cormullion Aug 15 '13 at 9:32
@cormullion (1) Yes. (2) That's correct AFAIK. –  Mr.Wizard Aug 15 '13 at 10:59
Well that's a little annoying... Thanks though. I'll mark as answer in a couple hours (assuming nothing else shows up). –  Daniel Aug 15 '13 at 17:21
@Mr.Wizard Under the documentation for Put, it states that expr >> filename is equivalent to expr >> "filename"`, and PutAppend is supposed to work the same as Put. Is this just misleading documentation? –  Daniel Aug 15 '13 at 18:10
@Daniel Actually I think that describes the behavior rather well: the point is you can omit the quotation marks and it behaves the same way. Since this behavior displeases you I'll see if I can provide a practical work-around. –  Mr.Wizard Aug 15 '13 at 21:40