Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Pitfalls met while opening multiple files

by foobarrior (Initiate)
on Jul 24, 2011 at 15:13 UTC ( #916417=perlquestion: print w/ replies, xml ) Need Help??
foobarrior has asked for the wisdom of the Perl Monks concerning the following question:

Hi all! I'm trying to do the following:
use warnings; use strict; open @$_ for ([\*STDIN, '< input.txt'], [\*STDOUT, '> output.txt']);
I just got

Can't use string ("2") as a symbol ref while "strict refs" in use at a.pl line 4.

But passing by one element works perfectly:
open $_->[0], $_->[1], $_->[2] for ([\*STDIN, '< input.txt'], [\*STDOUT, '> output.txt']);
But I think it looks ugly. Is there some way to do what I want?

Comment on Pitfalls met while opening multiple files
Select or Download Code
Re: Pitfalls met while opening multiple files
by armstd (Friar) on Jul 24, 2011 at 16:08 UTC

    Without digging into it, my guess is that you're hitting an issue with indirect object syntax. Maybe the syntax you'd like to use just removes too many hints for the compiler to figure out how to feed open properly.

    http://www.modernperlbooks.com/mt/2009/08/the-problems-with-indirect-object-notation.html
    http://perldoc.perl.org/perlobj.html#Indirect-Object-Syntax

    I think in this case, the brevity of your code is really not helping you. What other debugging steps have you taken? Have you tried breaking down your code, eliminating the for loop, etc? Do you know the value of $_->[2] in your example? (not that that has anything to do with your issue...) Since it's strict complaining, have you tried turning off strict refs to see if anything else goes wrong?

    --Dave

Re: Pitfalls met while opening multiple files
by moritz (Cardinal) on Jul 24, 2011 at 16:45 UTC
    The problem here is that open has a prototype, so it puts the @$_ in scalar context instead of interpolating it into the argument list.

    For normal routines that can be circumvented by calling it with an ampersand, &yourroutine(@$_). Unfortunately I don't know how that works with open, neither &CORE::open(@$_) nor &open(@$_) work.

    Perl 6 solves this problem by introducing a new syntax for explicitly interpolating arrays and hashes into argument lists, there it would be spelled open |@argumentlist.

      Ah yes, that makes perfect sense.

      --Dave

Re: Pitfalls met while opening multiple files
by chrestomanci (Priest) on Jul 24, 2011 at 17:05 UTC

    Are you actually trying to (re)open stdin or stdout, or where those just the name you picked for your filehandles? From your code it looks like you are doing normal file operations. If that is the case it is not a good idea to name your handles STDIN etc. At best it creates confusing code, at worst it will cause unexpected results.

    As armstd, it looks like your syntax may be confusing the compiler not to mention other programmers trying to read your code. Instead why not write:

    my @open_specs = ( { 'handle' => undef, 'file' => 'input.txt', 'mode' => '<', } # Fill in more files/modes here ); foreach my $open_spec (@open_specs) { my($file, $mode) = @$open_spec{'file', 'mode'}; # hash slic +e; my $fh; open $fh, $mode, $file or die "Error opening file $file in mode $m +ode $!"; $open_spec->{'handle'} = $fh; }

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://916417]
Approved by Corion
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (9)
As of 2014-08-20 08:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (107 votes), past polls