2011-02-05 8 views
2

スカラー結ばについて:私はtieを使用する必要がカウンタ変数を作成するために、しかしコンストラクタ私は私がこのようにそれを行う可能性が読まれるたびにインクリメントシンプル縛らスカラクラス持っていた場合は

package Counter; 

use strict; 
use warnings; 

sub TIESCALAR { 
    my $class = shift; 
    my $value = 0; 

    bless \$value, $class; 

    return \$value; 
} 

sub FETCH { 
    my $self = shift; 

    my $value = $$self; 

    $$self++; 

    return $value; 
} 

sub STORE { 
    my $self = shift; 
    $$self = shift; 
} 

1; 

を。私は1つのカウンタを作成してエクスポートすることができます。しかし、私が本当にやりたいことは、それをOOに見せることです。私がこのようなnewメソッドを作成することができると思わ:

sub new { 
    my $class = shift; 
    my $counter; 

    tie $counter, $class; 

    return $counter; 
} 

その後、私のメインのスクリプトで実行して二つのカウンタを取得:タイは「doesnのため

my $counter1 = Counter->new(); 
my $counter2 = Counter->new(); 

を、私はこれが動作しないと仮定していますコピー(私はどこかのドキュメントでそれを読んで)生き残る、これを行うには単純に方法はありますか?

NB。私はそれが唯一のスタイルの問題であることを知っていますが、それはより正確に見えるでしょう。

答えて

11

タイマジックは、変数自体に適用されるため、割り当てに渡されず、その値には適用されません。リファレンスを返す

:あなたはいくつかのオプションがあります

sub new {tie my $ret, ...; \$ret} 

my $counter = Counter->new; 

say $$counter; 

はグロブへの割り当て:

our ($counter); 

*counter = Counter->new; # same new as above 

say $counter; 

それとも、コンストラクタに変数を渡すことができます。

sub new {my $class = shift; tie $_[0], $class} 

Counter->new(my $counter); 

say $counter; 

両方の方法で動作するコンストラクタを作成することもできます:

sub new { 
    my $class = shift; 
    tie $_[0] => $class; 
    \$_[0] 
} 

our $glob; *glob = Counter->new; 

Counter->new(my $lexical); 

最後の2つの例では、tieには$_[0]が直接渡されます。これは、@_の要素が引数リストのエイリアスであるため、行にmy $counterと入力したように機能するためです。あなたの例は非常に明確であるとTIMTOWTDIの精神で、ベストプラクティスに従っている間


そして最後に、あなたはこのようにあなたの全体のクラスを書くことができる:

{package Counter; 
    sub TIESCALAR {bless [0]} 
    sub FETCH {$_[0][0]++} 
    sub STORE {$_[0][0] = $_[1]} 
    sub new {tie $_[1] => $_[0]; \$_[1]} 
} 

最後に一つにします言及。あなたの質問が結ば変数についてですが、あなたもこれを達成するためにオーバーロードを使用することができます。

{package Counter; 
    use overload fallback => 1, '""' => sub {$_[0][0]++}; 
    sub new {bless [0]} 
} 

my $counter = Counter->new; # overloading survives the assignment 

say $counter; 

しかし、あなたは割り当てを経由してカウンタをリセットする機能を失います。 Countersub set {$_[0][0] = $_[1]}メソッドを追加することができます。

+0

すばらしく完全な答えをありがとう! –

+0

また、 '@ _ 'の要素はエイリアスであり、どのように違いがあるのでしょうか。私はエイリアスが言及されている場所を見てきましたが、なぜそれが重要であると思うことができませんでした。ありがとう! –

関連する問題