This one got under my skin so I did a little research:
> use strict;
> use FileCache;
> my $a01;
> $a01 = 'a01file';
> cacheout $a01;
> print $a01 "XYZ\n";
It seems that perl decides that its calling print with arguments '$a01
"XYZ\n"' and then chokes on the argument list. Turns out that this is one
of those ambiguites of Perl's indirect object syntax. It caught me off
gaurd that cacheout $a01 turns a string into a file handle, I can't say that
I condone such things, but nobody asked me. Since $a01 is a file handle, we
can avoid using the indirect syntax by calling its print method:
use strict;
use IO::FileHandle;
use FileCache;
my $a01;
$a01 = 'a01file';
cacheout $a01;
$a01->print("XYZ\n");
Notice that I had to add "use IO::FileHandle". This is another curiosity,
why am I able to create IO::FileHandle objects when IO::FileHandle was not
accessable?
I know the technical answer is that Perl gives me the freedom to create any
kind of object I want. For example with "bless($myself, 'unicorn')" I can
turn $myself into a 'unicorn'. But in what sense can I consider $myself a
'unicorn' if I have no access to a package called 'unicorn' from which I may
access my methods. Maybe I shouldn't be able to turn into a 'unicorn'
unless I know what a 'unicorn' is. Does anyone know of a way to catch such
things.
It seems that "use FileCache" should imply "use IO::FileHandle" if it is
creating such objects. I guess what really disturbs me is that Perl isn't
playing by the rules by only considering file handles objects in a half
hearted sort of way. Why bother blessing them at all if behind the seens it
runs open, print, close etc without consulting the IO::FileHandle modules?
This seems to answer a question I had a while back. Why does Perl bother
with the tie function if you can create a new object that responds to all
the methods of a file. I think it has something to do with calling things
like:
print $pseudo_file "stuff"
would run into the same problem above and not translate to:
$pseudo_file->print("stuff");
Like
$pseudo_file = new PseudoFile;
translates to:
$pseudo_file = PseudoFile->new();
All I can say is I hope that we see stuff like this get cleaned up in Perl
6. Anyway, the above code does work and its kinda cleaner than the indirect
syntax anyway.
- Johnathan