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

This is probably an easy question for a perl expert, but I'm still a novice ;-)
I've assigned names for file handles I want to use into an array marctags but I can't work out the syntax to get the print command to use the values. Here's my latest failed attempt:
for $x (0..6) { print "$marctags[$x][3] $tagdata[$x]"; $tagdata[$x]=""; }

So first time I want it to:

print MAINOUT "blahblahblah";

Second time:

print LINKSOUT "blahblahblah";

and so on...

The output is going to the screen, so I can see I've got the arrays correct, just can't get it to use the file handles which I've opened to output to files on the disk.
Any advice to prevent me going crazy on this one would be appreciated - thanks.

Replies are listed 'Best First'.
Re: Interpolation of file handles in print
by BrowserUk (Patriarch) on May 17, 2005 at 10:35 UTC

    Try

    print { $marctags[$x][3] } $tagdata[$x];

    That will force perl to treat the fist parameter to print as an indirect object handle. I'll update with a link to the relevant docs when I find it. . No need. It's right there in preceding link.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
      The error is not caused by the print statement but by the open statement. This is documented.
      perldoc -f open shows:
      If FILEHANDLE is an undefined scalar variable (or array or hash element) the variable is assigned a reference to a new anonymous filehandle, otherwise if FILEHANDLE is an expression, its value is used as the name of the real filehandle wanted. (This is considered a symbolic reference, so "use strict 'refs'" should *not* be in effect.)
      Note the parenthetical phrase: (This is considered a symbolic reference, so "use strict 'refs'" should *not* be in effect.)

        From the OP's post:

        I've assigned names for file handles I want to use into an array marctags but I can't work out the syntax to get the print command to use the values.

        And:

        just can't get it to use the file handles which I've opened to output to files on the disk.

        Perhaps you could explain your post in the light of thise quotes, because I do not understand you?


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
      Thanks for all suggestions - I've learned something from each, but in the context of the rest of the code which I didn't include the one liner is the most appropriate solution. On to the next bit of coding now :-(
Re: Interpolation of file handles in print
by holli (Abbot) on May 17, 2005 at 10:20 UTC
    You could do something like the following:
    use FileHandle; my @files = ("file1", "file2", "file3", "file4", "file5", "file6", "f +ile7"); my @handles = map { my $fh = new FileHandle; $fh->open("< $_") ? $fh : undef; } @files; for $x (0..6) { my $h = $handles[$_]; print $h "$marctags[$x][3] $tagdata[$x]"; }
    (untested)


    holli, /regexed monk/
      Hello,

      This will work but not with use strict :

      #~ use strict ; use warnings ; my @marctags; my @tagdata ; $marctags[0]='FOO' ; $marctags[1]='BAR' ; open $marctags[0], ">foo.txt" or die "Failed"; open $marctags[1] , ">bar.txt" or die "Failed" ; $tagdata[0]="foo foo foo"; $tagdata[1]="bar bar bar"; for my $x (0..1) { print { $marctags[$x] } $tagdata[$x] ; }
      In perldoc -f print it says :
        Note that if you're storing FILEHANDLES in an array or other expression, you will have to use a block returning its value instead:

        print { $files[$i] } "stuff\n"; print { $OK ? STDOUT : STDERR } "stuff\n";

      use strict will raise a : Can't use string ("FOO") as a symbol ref while "strict refs" error that i don't know how to avoid here... So use FileHandle may be better :)

        Sometimes, you have to tell perl that you really do know what you're doing, and that it's not a mistake. You don't want to shut off warnings or strict for the whole program, but if there's a specific section that perl complains about, that is what you want, you can do something like the following:

        { no strict qw(refs subs); print { $OK ? STDOUT : STDERR } "stuff\n"; }