blazar has asked for the wisdom of the Perl Monks concerning the following question:

It seems that if the MODE parameter in a three args open contains IO layers and the third one is a scalar reference, then the latter is not open()ed in memory, but its stringification is interpreted as a filename:

picard:~ [10:30:46]$ perl -MFatal=open -e 'open F, "<", \"foo"' picard:~ [10:31:02]$ ^<^<:raw perl -MFatal=open -e 'open F, "<:raw", \"foo"' Can't open(F, <:raw, SCALAR(0x814fe04)): No such file or directory at +(eval 1) line 3 main::__ANON__('F', '<:raw', 'SCALAR(0x814fe04)') called at -e + line 1

and

picard:~ [10:35:09]$ perl -MFatal=open -e 'open F, ">", \$a' picard:~ [10:35:11]$ ^>^>:raw perl -MFatal=open -e 'open F, ">:raw", \$a' picard:~ [10:35:34]$ ls SCALAR\(0x814fe04\) SCALAR(0x814fe04)

Is this expected, documented, etc? I don't see anything in open()'s documentation to this effect...

Replies are listed 'Best First'.
Re: Clash between IO layers and "in memory" files?
by almut (Canon) on Mar 29, 2007 at 13:08 UTC

    What seems to work is to specify any layers in an extra binmode statement, i.e. while this doesn't work

    use Fatal "open"; open my $fh, "<:raw", \"foo"; print <$fh>, "\n"; --> dies with: Can't open(GLOB(0x65ea40), <:raw, SCALAR(0x65eaa0)): No such file or d +irectory at (eval 1) line 3 main::__ANON__('GLOB(0x65ea40)', '<:raw', 'SCALAR(0x65eaa0)') +called at ./openstr.pl line 5

    this does work

    open my $fh, "<", \"foo"; binmode $fh, ":raw"; print <$fh>, "\n"; --> prints: foo

    (Not sure if I'm telling you anything new -- just in case...)

    Anyway, I agree that this is kinda weird.

      (Not sure if I'm telling you anything new -- just in case...)

      Actually I stumbled into this issue when wanting to prepare a minimal example for a clpmisc post, and then I didn't think of it, so I eventually did something different. After having posted I did test with a separate binmode, but didn't include reference to it here because I wanted to stay concise (which is not a quality of mine!)

      Anyway, I agree that this is kinda weird.

      Indeed, I do not actually have a problem. I'm only puzzled by this behaviour: in some sense, it would make more sense if it didn't work with binmode either, don't you think so?

Re: Clash between IO layers and "in memory" files?
by Anno (Deacon) on Mar 29, 2007 at 09:11 UTC
    Similar behavior when you try to auto-open a string ref via @ARGV
    my $header_line = "Prepend this\n"; unshift @ARGV, \ $header_line; print while <>;
    results in
    Can't open SCALAR(0x816411c): No such file or directory at ...
    Anno
      Similar behavior when you try to auto-open a string ref via @ARGV

      Well, I had never thought of that and never seen it documented, although it would certainly be useful a feature to have. But it is somewhat annoying that e.g. '<' works and '<:raw' doesn't. perldoc -f open, now that I notice, only says:

      Since v5.8.0, perl has built using PerlIO by default. Unless you've changed this (i.e. Configure -Uuseperlio), you can open file handles to "in memory" files held in Perl scalars via: open($fh, '>', \$variable) || ..

      There's another example later (and no other ones) again with '>', but the technique also works in read mode and, now that I check, with '+>' and '+<'. OTOH it is not entirely clear if the above text is to mean that "in memory" files should be provided only in write mode or whenever the third argument is a scalar reference...

Re: Clash between IO layers and "in memory" files?
by sgt (Deacon) on Mar 29, 2007 at 13:30 UTC

    I get that too on cygwin with perl 5.8.7 :(

    % stephan@ape (/home/stephan) % % cat io_from_scalar.px #/usr/bin/perl -w $|++; my $io = qq{Just Aother\n Perl hacker\n}; { print ". trying IO from memory -- default layer\n"; open my $fh1, "<", \$io or die; print ">> ok, fh from memory -- default layer\n"; } { print ". trying IO from memory -- (explicit) unix layer\n"; open my $fh2, "<:unix", \$io or die; print "ok, fh from memory -- unix layer"; }
    % # result % stephan@ape (/home/stephan) % % perl io_from_scalar.px . trying IO from memory -- default layer >> ok, fh from memory -- default layer . trying IO from memory -- (explicit) unix layer Died at io_from_scalar.px line 14.
    cheers --stephan