Frage

Ich habe gerade angefangen zu zu lernen tie . Ich habe eine Klasse namens Link, ich möchte folgende Sache tun:

  • wenn geholt, kehrt den Link Adresse
  • wenn gespeichert, speichern Sie die neue Adresse
  • der Lage sein, Methoden auf sie anrufen

Bisher ist mein Code:


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;

Und der Code, den ich mit der Funktionalität zu überprüfen ist:


use Link;

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

Wenn läuft, wird das Skript mit dem folgenden Fehler beendet: Die Methode kann nicht „print_method“ aufrufen, ohne ein Paket oder Objektreferenz auf tietest.pl Linie 4. .

Wenn ich seine Botschaft richtig verstanden habe, $var->print_method löst bis zu einem gewissen Zeichenfolge, auf dem die Methode print_method bezeichnet wird. Wie könnte ich von tie profitieren, sondern auch die Variable als Objekt verwenden?

EDIT: nach ein wenig experimentieren, fand ich heraus, dass, wenn ich $ selbst auf Abruf zurückzukehren, ich die Methoden aufrufen können, jedoch holen die Adresse nicht zurück

.

EDIT 2: Die Perl-Mönche versorgen mir die Lösung: gebunden . gebunden wird eine Referenz auf das Objekt-Variable zurück.

Durch die Zusammenarbeit mit meinen Methoden gebunden kombiniert, kann ich alles erreichen wollte ich.

War es hilfreich?

Lösung

Krawatte ist das falsche Werkzeug für diesen Job. Sie verwenden Verbindungen, wenn Sie die gleiche Schnittstelle wie normale Datentypen wollen aber anpassen wollen, wie die Operationen tun ihre Arbeit. Da Sie eine Zeichenfolge nur für den Zugriff auf und speichern wollen, wie ein Skalar bereits tut, tut Krawatte nichts für Sie.

Es sieht aus wie Sie die URI Modul oder eine Unterklasse davon, und vielleicht einige Überlastung.

Wenn Sie das wirklich tun müssen, müssen Sie die richtige Variable verwenden. Die tie die Variable bis Haken Sie auf die Klasse geben Sie angeben, aber es ist immer noch ein normale skalare (und nicht um eine Referenz). Sie haben die Aufgabe, es zu benutzen zurückgibt, wenn Sie Methoden aufrufen:

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

Sie können auch das geheime Objekt, wenn man nur den gebunden Skalar hat:

my $secret_object = tied $normal_scalar;

Ich habe ein ganzes Kapitel über tie in Mastering Perl .

Andere Tipps

Ich schlage vor, dass ein normales Perl-Objekt und dann Überlastung ing stringification. Sie verlieren die Fähigkeit, einen Wert durch Zuordnung zu speichern, sondern behalten die Fähigkeit, durch den Druck des Objekts um den Wert zu bekommen. Sobald Sie Methoden wollen beginnen direkt anrufen, ein Objekt ist wahrscheinlich das, was Sie wollen.

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;

Beispiel Nutzung:

use Link;

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

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

Wenn Sie wirklich, wirklich wollen Zuordnung zu arbeiten, können Sie ein normales Objekt mit überladener stringification kombinieren (Link, oben) mit 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;

Beispiel Nutzung:

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

Das ist alles ziemlich scheußlich und ein langer Weg zu gehen, nur die zweifelhafte Fähigkeit zu bekommen, um etwas zuweisen, die Sie auch Methoden auf und auch auszudrucken wie besehen aufrufen können. Ein Standard-URI-Objekt mit stringification ist wahrscheinlich eine bessere Wette.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top