문제

방금 배우기 시작했습니다 묶다. 다음과 같은 일을하고 싶은 링크라는 클래스가 있습니다.

  • 가져 오면 링크의 주소를 반환하십시오
  • 저장된 경우 새 주소를 저장하십시오
  • 그것에 메소드를 호출 할 수 있습니다

지금까지 내 코드는 다음과 같습니다.


package Link;

sub FETCH {
    my $this = shift;
    return $this->{"site"};
}

sub STORE {
    my ($self,$site) = @_;
    $self->{"site"}   = $site;
}

sub print_method {
    my $self = shift;
    print $self->{"site"};
}

sub TIESCALAR {
    my $class = shift;
    my $link  = shift;
    my $this  = {};
    bless($this,$class);
    $this->{"site"} = $link;
    return $this;
}

1;

그리고 기능을 확인하는 데 사용하는 코드는 다음과 같습니다.


use Link;

tie my $var,"Link","http://somesite.com";
$var->print_method;

실행되면 스크립트가 다음 오류로 종료됩니다.tietest.pl line 4에서 패키지 나 객체 참조없이 메소드 "print_method"를 호출 할 수 없습니다..

메시지를 올바르게 이해하면 $var->print_method 메소드가있는 일부 문자열로 해결됩니다 print_method 호출됩니다. 넥타이로부터 어떻게 이익을 얻을 수있을뿐만 아니라 변수를 객체로 사용할 수 있습니까?

편집 : 약간의 실험 후, 나는 Fetch에서 $ $ self를 반환하면 방법을 호출 할 수 있지만 Fetch는 주소를 반환하지 않을 것임을 알았습니다.

편집 2 : Perl Monks가 나에게 해결책을 제공했습니다. 묶여 . Tied는 객체 변수에 대한 참조를 반환합니다.

내 방법과 결합하여 원하는 모든 것을 성취 할 수 있습니다.

도움이 되었습니까?

해결책

넥타이는이 작업에 잘못된 도구입니다. 일반 데이터 유형과 동일한 인터페이스를 원하지만 작업의 작업 방식을 사용자 정의하려는 경우 Ties를 사용합니다. 이미 스칼라처럼 끈에 액세스하고 저장하고 싶기 때문에 넥타이는 당신을 위해 아무것도하지 않습니다.

당신이 원하는 것 같습니다 우리 모듈 또는 서브 클래스 및 아마도 과부하.

실제로이를 수행 해야하는 경우 올바른 변수를 사용해야합니다. 그만큼 묶다 지정한 클래스에 지정한 변수를 연결하지만 여전히 일반 스칼라 (참조가 아닌)입니다. 메소드를 호출하려면 반환하는 객체를 사용해야합니다.

my $secret_object = tie my($normal_scalar), 'Tie::Class', @args;
$secret_object->print_method;

묶인 스칼라 만있는 경우 비밀 물체를 얻을 수도 있습니다.

my $secret_object = tied $normal_scalar;

넥타이에 대한 전체 장이 있습니다 마스터 링 Perl.

다른 팁

일반적인 Perl 객체를 만드는 것이 좋습니다 초과 적재ingringification. 과제를 통해 값을 저장하는 능력이 상실되지만 객체를 인쇄하여 값을 얻을 수있는 능력을 유지합니다. 메소드를 직접 호출하기 시작하면 물체가 원하는 것일 것입니다.

package Link;

use strict;
use Carp;

use overload
(
  '""'      => sub { shift->site },
   fallback => 1,
);

sub new 
{
  my $class = shift;

  my $self = bless {}, $class;

  if(@_)
  {
    if(@_ == 1)
    {
      $self->{'site'} = shift;
    }
    else { croak "$class->new() expects a single URL argument" }
  }

  return $self;
}

sub site
{
  my $self = shift;
  $self->{'site'} = shift  if(@_);
  return $self->{'site'};
}

sub print_method
{
  my $self = shift;
  print $self->site, "\n";
}

1;

예제 사용 :

use Link;

my $link = Link->new('http://somesite.com');

print $link, "\n";   # http://somesite.com
$link->print_method; # http://somesite.com

당신이 정말로, 정말로 일을 할 과제를 원한다면, 일반적인 객체와 오버로드 된 문자열 화를 결합 할 수 있습니다 (Link, 위)와 tie:

package LinkTie;

use strict;
use Link;

sub FETCH
{
  my $this = shift;
  return $this->{'link'};
}

sub STORE
{
  my($self, $site) = @_;
  $self->{'link'}->site($site);
  return $site;
}

# XXX: You could generalize this delegation with Class::Delegation or similar
sub print_method
{
  my $self = shift;
  print $self->{'link'}->print_method;
}

sub TIESCALAR
{
  my $class = shift;
  my $self = bless {}, $class;
  $self->{'link'} = Link->new(@_);
  return $self;
}

1;

예제 사용 :

tie my $link,'LinkTie','http://somesite.com';
print $link, "\n";   # http://somesite.com
$link->print_method; # http://somesite.com

$link = 'http://othersite.com';

print $link, "\n";   # http://othersite.com
$link->print_method; # http://othersite.com

이것은 모두 매우 끔찍하며 방법으로 전화를 걸고 인쇄 할 수있는 무언가에 할당 할 수있는 모호한 능력을 얻는 데 큰 도움이됩니다. 줄화성이있는 표준 URI 객체는 아마도 더 나은 내기 일 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top