7

名前付き引数を使用して字句ファイルハンドルをサブルーチンに渡したいのですが、以下はコンパイルされません。

#!/usr/bin/perl -w
use strict;

my $log_fh;
my $logname = "my.log";

sub primitive {
   my ($fh, $m) = @_;
   print $fh $m;
}

sub sophisticated {
   my ($args) = @_;
   print $args->{m};
   print $args->{fh} $args->{m} ;
}

open $log_fh, ">", $logname;

print $log_fh "Today I learned ...\n";

primitive($log_fh,"... the old way works ...\n");

sophisticated({
   fh=>$log_fh, 
   m=>"... and the new way requires an intervention by SO.",
   });
close $log_fh;

苦情は次のとおりです。

Scalar found where operator expected at ./lexical.file.handle.pl line 15, near
} $args"
(Missing operator before  $args?)

$ perl --version

This is perl, v5.10.1

引数を渡すという基本的な手法を使用すると問題なく機能します。名前付き引数のハッシュ手法は、ファイルハンドル部分ではなく、メッセージ部分に対して機能します。新しいバージョンの印刷物が必要ですか?

4

2 に答える 2

17

(のような)ファイルハンドルを返す複雑な式がある$args->{fh}場合は、いくつかの余分なカーリーを追加して、構文を少し明確にする必要があります。

print { $args->{fh} } $args->{m};

これはprint、ファイルハンドルと印刷するもののリストの間にコンマがない、演算子の設計方法がおかしいためです。

または、最初に引数hashrefからファイルハンドルを取得することもできます。

my $fh = $args->{fh};
print $fh $args->{m};
于 2010-06-25T18:32:07.063 に答える
4

friedoの答えはあなたの問題をカバーしていますが、私が指摘したい文体の問題があります。名前付き引数をエミュレートするために、すべてを匿名ハッシュでラップする必要はありません。ハッシュ初期化子は、キーと値のペアとして解釈される単なるリストです。このようなリストをサブに渡すと、呼び出し元にわかりやすい構文が提供されます。

sub sophisticated {
   my %arg = @_;
   print $arg{m};
   print {$arg{fh}} $arg{m};
}

sophisticated(fh => $log_fh, m => "Hello, world!\n");
于 2010-06-25T18:49:12.180 に答える