Question

Je viens juste de commencer à apprendre sur lien . J'ai une classe nommée lien que je voudrais faire la chose suivante:

  • si tiré par les cheveux, retourner l'adresse du lien
  • si, mémorisez la nouvelle adresse
  • être en mesure d'appeler des méthodes sur elle

Jusqu'à présent, mon code est:


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;

Et le code que je utilise pour vérifier la fonctionnalité est:


use Link;

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

couru, le script se terminera avec l'erreur suivante: Impossible d'appeler la méthode « print_method » sans référence de colis ou objet à la ligne de 4 tietest.pl. .

Si je comprends son message correctement, $var->print_method décide de la ficelle sur laquelle la méthode print_method est appelé. Comment pourrais-je bénéficier de cravate, mais aussi utiliser la variable comme un objet?

EDIT: après avoir expérimenté un peu, j'ai découvert que si je retourne $ moi sur chercher, je peux appeler les méthodes, cependant, chercher ne reviendra pas l'adresse

.

EDIT 2: les moines Perl me ont fourni la solution: liée . égalité renvoie une référence à la variable objet.

En combinant à égalité avec mes méthodes, je peux accomplir tout ce que je voulais.

Était-ce utile?

La solution

Tie est le mauvais outil pour ce travail. Vous utilisez des liens quand vous voulez la même interface que les types de données normales mais que vous souhaitez personnaliser la façon dont les opérations font leur travail. Puisque vous voulez accéder et stocker une chaîne comme un scalaire fait déjà, une cravate ne fait rien pour vous.

On dirait que vous voulez que le URI , ou une sous-classe de celui-ci, et peut-être une surcharge.

Si vous avez vraiment besoin de faire cela, vous devez utiliser la variable droite. cravate crochets la variable que vous spécifiez à la classe que vous spécifiez, mais il est encore scalaire normal (et non pas une référence). Vous devez utiliser l'objet retourne si vous voulez appeler des méthodes:

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

Vous pouvez également obtenir l'objet secret si vous avez seulement le scalaire lié:

my $secret_object = tied $normal_scalar;

J'ai un chapitre entier sur cravate dans Mastering Perl .

Autres conseils

Je suggère faire un objet Perl normal et puis surcharge ing mise en chaîne. Vous perdez la possibilité de stocker une valeur par cession, tout en conservant la possibilité d'obtenir la valeur en imprimant l'objet. Une fois que vous commencez à vouloir appeler des méthodes directement, un objet est probablement ce que vous voulez.

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;

Exemple d'utilisation:

use Link;

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

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

Si vous avez vraiment, vraiment envie de travailler aussi l'affectation, vous pouvez combiner un objet normal avec surcharge mise en chaîne (de Link, ci-dessus) avec 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;

Exemple d'utilisation:

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

Ceci est d'autant tout à fait hideux et un long chemin à parcourir juste pour obtenir la capacité douteuse à attribuer à quelque chose que vous pouvez également appeler des méthodes sur et imprimer également en l'état. Un objet URI standard avec est probablement une mise en chaîne meilleur pari.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top