LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Problem accessing filehandles (Perl). (https://www.linuxquestions.org/questions/programming-9/problem-accessing-filehandles-perl-808384/)

MheAd 05-17-2010 01:14 PM

Problem accessing filehandles (Perl).
 
Hi guys,
I've been reading / trying to learn some Perl lately. I've found the free book, "Learning Perl", quite good and easy to follow most of the times. However, today I was testing one of the scripts in the book and it would only run partly.

Code:

#!/usr/bin/perl

use warnings;
use strict;

my %inventory;
print "Enter individual items, followed by a new line.\n";
print "Enter a blank line to finish.\n";

while (1) {
        my $item = <STDIN>;
        chomp $item;
        last unless $item;
        $inventory{lc $item}++;
}

open (SORT, "| perl sort.plx") or *SORT = *STDOUT;
select *SORT;

while (my ($item, $quantity) = each %inventory) {
        if ($quantity > 1) {
                $item =~ s/^(\w+)\b/$1s/ unless $item =~ /^\w+s\b/;
        }
        print "$item: $quantity\n";
}

The problem is the open(SORT...) row.
This row is supposed to give option, either to use an additional script as pipe (sort.plx), or STDOUT if the extra script is not found.

It works with the other script present, however, with the sort.plx being absent it simply wont use STDOUT instead but whines to me:

Can't open perl script "sort.plx": No such file or directory

Has the author of the original script done some error writing it? Since I'm a beginner and found most of the stuff confusing in Perl either way (having previously only experience in Bash and some in PHP) - I can't really tell for sure :), but from what I can read in documentation - it doesn't appear to be wrong.

As it looks now, the only way for me to use STDOUT is only by removing:
open (SORT, "| perl sort.plx") or *SORT = *STDOUT;
select *SORT;

rows. But then, I lose the piping in to that other script as an option.

Any ideas? Thanks in advance.

timetraveler 05-17-2010 01:53 PM

use warnings;

Can comment out and try.

MheAd 05-17-2010 01:57 PM

Hi,
No effect after I did what you suggested.

Sergei Steshenko 05-17-2010 02:04 PM

Quote:

Originally Posted by MheAd (Post 3971705)
Hi guys,
I've been reading / trying to learn some Perl lately. I've found the free book, "Learning Perl", quite good and easy to follow most of the times. However, today I was testing one of the scripts in the book and it would only run partly.

Code:

#!/usr/bin/perl

use warnings;
use strict;

my %inventory;
print "Enter individual items, followed by a new line.\n";
print "Enter a blank line to finish.\n";

while (1) {
        my $item = <STDIN>;
        chomp $item;
        last unless $item;
        $inventory{lc $item}++;
}

open (SORT, "| perl sort.plx") or *SORT = *STDOUT;
select *SORT;

while (my ($item, $quantity) = each %inventory) {
        if ($quantity > 1) {
                $item =~ s/^(\w+)\b/$1s/ unless $item =~ /^\w+s\b/;
        }
        print "$item: $quantity\n";
}

The problem is the open(SORT...) row.
This row is supposed to give option, either to use an additional script as pipe (sort.plx), or STDOUT if the extra script is not found.

It works with the other script present, however, with the sort.plx being absent it simply wont use STDOUT instead but whines to me:

Can't open perl script "sort.plx": No such file or directory

Has the author of the original script done some error writing it? Since I'm a beginner and found most of the stuff confusing in Perl either way (having previously only experience in Bash and some in PHP) - I can't really tell for sure :), but from what I can read in documentation - it doesn't appear to be wrong.

As it looks now, the only way for me to use STDOUT is only by removing:
open (SORT, "| perl sort.plx") or *SORT = *STDOUT;
select *SORT;

rows. But then, I use the piping in to that other script as an option.

Any ideas? Thanks in advance.

The whole idea of modifying global entities is wrong/bad. You do not need 'select'. In Perl one can (and should) use lexical variables as file handles. I.e. something like this:

Code:

my $sort_fh;
open ($sort_fh, "| perl sort.plx") or do{$sort_fh = \*STDOUT};

...

  print $sort_fh "$item: $quantity\n";
...

.

MheAd 05-17-2010 02:13 PM

After applying your suggestion, the script did actually manage to print output, correctly too, but the error message still persists (even without use strict / use warnings).

Also, this is the first time I read that lexical variables should be used as standard file handles.

Any other ideas?

Sergei Steshenko 05-17-2010 02:59 PM

Quote:

Originally Posted by MheAd (Post 3971782)
After applying your suggestion, the script did actually manage to print output, correctly too, but the error message still persists (even without use strict / use warnings).

Also, this is the first time I read that lexical variables should be used as standard file handles.

Any other ideas?

And why do you think the error message shouldn't persist ?

...

If you read 'perldoc -f open', you'll see a number of examples with lexical variable as file handle.

MheAd 05-17-2010 03:11 PM

I've seen few lexical variables in the doc file, yes.
But two books are telling me so far that it's not the standard way to go.
And since I'm trying to learn Perl here, I'm asking the question that teachers hear many times - 'why?' - so I know this for the future reference. Because, you seem to be encouraging the usage.

Sergei Steshenko 05-17-2010 03:18 PM

Quote:

Originally Posted by MheAd (Post 3971849)
I've seen few lexical variables in the doc file, yes.
But two books are telling me so far that it's not the standard way to go.
And since I'm trying to learn Perl here, I'm asking the question that teachers hear many times - 'why?' - so I know this for the future reference. Because, you seem to be encouraging the usage.

I really do not care about Perl books. Global vs lexical is a general concern, and the the book authors seem to be copying ancient examples from the Perl 4 era.

So, have you come to a conclusion about the error message ?

chrism01 05-18-2010 08:41 PM

You may want to bookmark the official Perl docs here http://perldoc.perl.org/ See also the extra tutorials http://www.perlmonks.org/?node=Tutorials


All times are GMT -5. The time now is 09:01 AM.