2011-02-05 4 views
2

나는 내가 이런 것을 할 수있는 읽을 때마다 증가하는 간단한 연결 스칼라 클래스를 가지고 있다면 : 생성자 묶여 스칼라

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; 

그러나 나는 tie를 사용해야하는 카운터 변수를 만들 수 있습니다. 하나의 카운터를 만들어서 내보낼 수 있습니다. 하지만 내가 정말로하고 싶은 것은 그것이 OO로 보이게 만드는 것입니다. 다음

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

    tie $counter, $class; 

    return $counter; 
} 

내 주요 스크립트에서 수행하여 두 개의 카운터를 얻을 : 나는 넥타이 '아무튼 때문에이 작동하지 않는 가정입니다

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

을 내가 이런 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); 

마지막 두 예제에서 tie$_[0]으로 직접 전달됩니다. 그 이유는 @_의 요소가 인수 목록의 별칭이므로 tie 행에 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

또한'@ _ '의 엘리먼트가 별칭이고 그것이 어떻게 다른지 알 수 있습니다. 별칭이 언급 된 곳을 보았지만 왜 중요해야하는지 생각할 수 없었습니다. 감사! –