3-argument open on STDIN

3-argument open on STDIN

am 18.08.2011 00:53:59 von Bryan R Harris

How can I do a 3-argument open on STDIN? This doesn't work because the
3-argument open won't open STDIN when you tell it to open "-".

**************************************
@files = ("-");

for (@files) {
print reverse readfile($_);
}

sub readfile {

open(my $fh,"<",$_[0]) or die "$me: Couldn't open $_[0]: $!\n";
my(@fc) = <$fh>;
close($fh) or die "$me: Couldn't close $_[0]: $!\n";
if ($fc[0] =~ /\r/) { @fc = map { s/\r\n?/\n/g; split /(?<=\n)/ } @fc; }
if (wantarray()) { return @fc; }
else { return join('', @fc) }
}
**************************************

How can I use the "safe" 3-argument open and still be able to read off a
pipe?

- Bryan




--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: 3-argument open on STDIN

am 18.08.2011 01:10:20 von Brandon McCaig

On Wed, Aug 17, 2011 at 6:53 PM, Bryan R Harris
wrote:
> How can I use the "safe" 3-argument open and still be able to read off a
> pipe?

What I have done in the past is manually compare the filename to '-'
and skip the opening and just assign STDIN to my file handle.

use strict;
use warnings;

my @filenames = qw(-);

@filenames = @ARGV if @ARGV;

for my $filename (@filenames)
{
my $fh;

if($filename eq '-')
{
$fh = \*STDIN;
}
else
{
open $fh, '<', $filename or die "Failed to open '$filename': $!";
}

# Etc...
}

__END__

Perhaps experienced Perl programmers know of better ways, in which
case I would be happy to learn them also. :)


--
Brandon McCaig
V zrna gur orfg jvgu jung V fnl. Vg qbrfa'g nyjnlf fbhaq gung jnl.
Castopulence Software

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: 3-argument open on STDIN

am 18.08.2011 02:35:47 von John Delacour

At 17:53 -0500 17/08/2011, Bryan R Harris wrote:


>How can I do a 3-argument open on STDIN? This doesn't work because the
>3-argument open won't open STDIN when you tell it to open "-".
>
>**************************************
>@files = ("-");
>
>for (@files) {
> print reverse readfile($_);
>}
>[...]


That makes no sense to me at all. I see no mention of STDIN in the
script and see you are trying to open and read a single file named
"-", which is pretty odd.

If this below is your script "test.pl" and you run it from the
Terminal or command line...


#!/usr/bin/perl
use strict;
use warnings;
print "Enter file names separated by space\n--> ";
my @files = split /\s+/, ;
foreach my $file (@files){
undef my @lines;
open my $fh, "<$file" or die $!;
print "\n____File: $file\____\n";
while (<$fh>){
chomp;
unshift @lines, $_;
}
for (@lines){
print "$_\n";
}
}
END


This is what you will get:


>>> perl test.pl
Enter file names separated by space
--> a.txt b.txt c.txt

____File: a.txt____
e
d
c
b
a

____File: b.txt____
j
i
h
g
f

____File: c.txt____
o
n
m
l
k

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: 3-argument open on STDIN

am 18.08.2011 03:57:44 von Rob Dixon

On 18/08/2011 01:35, John Delacour wrote:
> At 17:53 -0500 17/08/2011, Bryan R Harris wrote:
>
>
>> How can I do a 3-argument open on STDIN? This doesn't work because the
>> 3-argument open won't open STDIN when you tell it to open "-".
>>
>> **************************************
>> @files = ("-");
>>
>> for (@files) {
>> print reverse readfile($_);
>> }
>> [...]
>
>
> That makes no sense to me at all. I see no mention of STDIN in the
> script and see you are trying to open and read a single file named "-",
> which is pretty odd.

Hi John

Bryan is referring to a poorly-documented feature of Perl, which as far
as I know is only described in perldoc perlopentut. This is what it says:

> The Minus File
> Again following the lead of the standard shell utilities, Perl's "open"
> function treats a file whose name is a single minus, "-", in a special
> way. If you open minus for reading, it really means to access the
> standard input. If you open minus for writing, it really means to access
> the standard output.

And the problem is that, while

open my $fh, '-';

or

open my $fh, '<-';

opens a copy of the STDIN filehandle, the three-argument form of open

open my $fh, '<', '-';

looks instead for a real file called '-' and fails if it doesn't find
one. Brandon's solution is the only one I can think of.

Rob

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: 3-argument open on STDIN

am 18.08.2011 04:11:57 von Shawn H Corey

On 11-08-17 06:53 PM, Bryan R Harris wrote:
>
>
> How can I do a 3-argument open on STDIN? This doesn't work because the
> 3-argument open won't open STDIN when you tell it to open "-".
>
> **************************************
> @files = ("-");
>
> for (@files) {
> print reverse readfile($_);
> }
>
> sub readfile {
>
> open(my $fh,"<",$_[0]) or die "$me: Couldn't open $_[0]: $!\n";
> my(@fc) =<$fh>;
> close($fh) or die "$me: Couldn't close $_[0]: $!\n";
> if ($fc[0] =~ /\r/) { @fc = map { s/\r\n?/\n/g; split /(?<=\n)/ } @fc; }
> if (wantarray()) { return @fc; }
> else { return join('', @fc) }
> }
> **************************************
>
> How can I use the "safe" 3-argument open and still be able to read off a
> pipe?
>
> - Bryan
>
>
>
>

Well, this doesn't use the 3-argument open but it gets the job done.

#!/usr/bin/env perl

use strict;
use warnings;

my @files = ( $0, '-', $0 );

for my $file ( @files ){
print reverse readfile( $file );
}

sub readfile {
local @ARGV = @_;
my ( @fc ) = <>;

# as above

return wantarray ? @fc : join( '', @fc );
}

__END__


--
Just my 0.00000002 million dollars worth,
Shawn

Confusion is the first step of understanding.

Programming is as much about organization and communication
as it is about coding.

The secret to great software: Fail early & often.

Eliminate software piracy: use only FLOSS.

"Make something worthwhile." -- Dear Hunter

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/