Re: There be dragons (or, perl5.8's open stringref breaks...)
by toma (Vicar) on Apr 23, 2005 at 03:30 UTC
|
To change everything you do with IO all at once,
check out IO::All. It handles the
'or whatever' anything->anything part of what you're doing.
use IO::All;
my $buffer = <<EOS;
Here there be dragons!
EOS
io("foo.txt") < $buffer;
I keep my
IO bag-o-tricks
offsite.
It should work perfectly the first time! - toma
| [reply] [d/l] |
Re: There be dragons (or, perl5.8's open stringref breaks...)
by dragonchild (Archbishop) on Apr 23, 2005 at 02:17 UTC
|
There's two problems here. The first is stat() and the second is sysread() (and, I would presume, syswrite() as well). stat() treats scalar filehandles as unopened. If you comment out that section in File::Copy::copy(), sysread() treats it as a "Bad file descriptor". I would argue that both are bugs, but that's because they violate the Principle of Least Surprise.
| [reply] |
|
|
So it is arguably doing the right thing and they are not bugs, at least not bugs in the binary but in the dox somewhere. As mentioned there, they don't
actually exist. At least, such an argument could be made for sys*. Stat ought to be able to fake most things for a scalar easily enough, although one could argue sys* aren't that hard either. It's either a gross oversight on somebody's part, or a big can of worms they decided to consider Somebody Else's Problem.
| [reply] |
|
|
They aren't bugs in implementation, but in specification. This is why you need requirements and design reviews along with code reviews.
The Perfect is the Enemy of the Good.
| [reply] |
Re: There be dragons (or, perl5.8's open stringref breaks...)
by ikegami (Patriarch) on Apr 23, 2005 at 00:37 UTC
|
#!/usr/bin/perl
use strict;
use warnings;
use File::Copy;
my $buffer = <<EOS;
Here there be dragons!
EOS
open my $fh, '>', 'foo.txt';
print $fh $buffer;
| [reply] [d/l] |
|
|
This code is a simplified example. The real code is much bigger and more complex. And is used for everything from getting data from pipelines (open my $fh, "tar cf - * | gzip -c |";) carrying hundreds of MB of data, to a couple KB of strings. The latter isn't a big deal, the former is. I'm figuring that I'm going to have to perform the copy myself. Not hard to do, but just has to be done. Note that I can't assume anything about the data, so if I want to be efficient (time/memory), I'm going to either have to use sysread or something, or I'm going to have to set $/ to \1024 or something (fixed length read/write, not line-by-line since, as potentially binary data, I don't have any idea what lines are). Not a big deal, but this is what I was using File::Copy for. :-)
I'm just going to rip some of it from File::Copy, and assume the filehandle is good. I do know, however, that the from-handle and the to-filename should not be the same (it would actually be difficult to do), so this should be ok for all but the pathological cases (where someone is simply trying to break something on purpose).
Thanks!
| [reply] [d/l] |
Re: There be dragons (or, perl5.8's open stringref breaks...)
by tlm (Prior) on Apr 23, 2005 at 01:04 UTC
|
FWIW, fileno returns -1 for handles pointing to scalar refs, though this behavior appears to be undocumented; at least the docs for fileno are noncommittal on the subject.
| [reply] |
Re: There be dragons (or, perl5.8's open stringref breaks...)
by starbolin (Hermit) on Apr 23, 2005 at 14:19 UTC
|
Interesting, this code compiles and runs, but the data isn't copied.
#!/usr/bin/perl
use strict;
use warnings;
use File::Copy;
my $buffer = <<EOS;
Here there be dragons!
EOS
copy(\$buffer, "foo.txt");
Update:
My bad. The Copy chokes on a non-filehandle.
s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s
|-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,,
$|=1,select$,,$,,$,,1e-1;print;redo}
| [reply] [d/l] |
Re: There be dragons (or, perl5.8's open stringref breaks...)
by salva (Canon) on Apr 24, 2005 at 13:04 UTC
|
| [reply] |
|
|
Yeah ... I was hoping the PerlIO abstracted this, too ;-)
What would be really cool is to be able to do this:
{
local *STDOUT;
my $buf;
open STDOUT, '>', \$buf;
system("some_command","with","args");
$logger->write($buf);
}
But that's probably expecting a bit much. ;-)
Anyway, as I said in the original post of the thread, I can't quite figure out who the author is - probably owned by p5p anyway. So I submitted the bug report - we'll see if there's any answer. I do still think, however, that this is a much larger problem than I would be able to give a reasonable patch for, since getting it to work properly may involve many, many changes, or just one: disallow string-handles in File::Copy. | [reply] [d/l] |