简体   繁体   中英

In perl how can I print to a file whose filehandle is resolved at the runtime?

I have the following code:

use strict;
my $org_file_hash = {
      'S6' => '/path/to/file/filename.txt_S6',
      'S8' => '/path/to/file/filename.txt_S8',
      'S2' => '/path/to/file/filename.txt_S2',
      'S0' => '/path/to/file/filename.txt_S0',
      'S00' => '/path/to/file/filename.txt_S00'
    };
my $filehandles;
for(keys %{$org_file_hash})
{
    my $key=$_;
    open(my $key,">",$org_file_hash->{$key}) || die "Cannot open ".$org_file_hash->{$key}." for writing: $!";
    push(@{$filehandles},$key);
}

In the latter part of the code, I get $org as "S2".

my $org="S2";

Based on $org I will decide the file I need to print to and in this case it is /path/to/file/filename.txt_S2.

To achieve this, I am doing following, but it does not work:

my $org="S2";
print {$org} "hello world\n";

I get the following error:

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

Please help.

Use $filehandles as a hash (or hashref) instead of an arrayref, as such:

my $filehandles = {};
for my $key (keys %{$org_file_hash})
{
    # my $key=$_;     # redundant
    open( my $fh, '>', $org_file_hash->{$key} )
        or die "Cannot open ".$org_file_hash->{$key}." for writing: $!";
    $filehandles->{$key} = $fh;
}

# later...
my $org = 'S2';
print { $filehandles->{$org} } "Hello, world.\n";

At the end, don't forget to iterate over keys %{$filehandles} and close your open ed files, too.

Use a hash:

my $filehandles = {};

for my $key (keys %{$org_file_hash}) {
    open my $fh, ">", $org_file_hash->{$key} or die $!;    
    $filehandles->{$key} = $fh;    
}
my $org="S2";
print {$filehandles->{$org}} "hello world\n";

BTW, if you use the open my $fh, ... form of open , $fh should be undefined. Otherwise, its value is used as the name of the real filehandle wanted. This is considered a symbolic reference, so the script won't compile under " use strict 'refs' ".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM