Domanda

Ho appena iniziato a conoscere legame . Ho una classe denominata link che vorrei fare la seguente cosa:

  • se inverosimile, l'indirizzo di ritorno del collegamento
  • se conservato, memorizzare il nuovo indirizzo
  • essere in grado di chiamare i metodi su di esso

Finora, il mio codice è:


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;

E il codice che sto utilizzando per verificare la funzionalità è:


use Link;

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

Quando correva, lo script terminerà con il seguente errore: Impossibile chiamare il metodo "print_method" senza un riferimento pacco o di un oggetto alla linea tietest.pl 4. .

Se ho capito bene il suo messaggio, $var->print_method si risolve in una stringa su cui il metodo di print_method si chiama. Come avrei potuto beneficiare di cravatta, ma anche utilizzare la variabile come un oggetto?

EDIT: dopo aver sperimentato un po ', ho scoperto che se torno $ sé il prendere, posso chiamare i metodi, tuttavia, prendere non tornerà l'indirizzo

.

EDIT 2: i monaci perl mi ha fornito la soluzione: legato . legato restituirà un riferimento alla variabile di oggetto.

Grazie alla combinazione legato con i miei metodi, posso fare tutto quello che volevo.

È stato utile?

Soluzione

Tie è lo strumento sbagliato per questo lavoro. È possibile utilizzare i legami quando si desidera che la stessa interfaccia normali tipi di dati, ma desidera personalizzare come le operazioni di fare il loro lavoro. Dal momento che si desidera accedere e memorizzare una stringa, proprio come uno scalare fa già, cravatta non fa nulla per te.

Sembra che si desidera che il URI modulo o una sottoclasse di esso, e, forse, un po 'sovraccarico.

Se si ha realmente bisogno di fare questo, è necessario utilizzare la variabile a destra. Il cravatta aggancia la variabile si specifica alla classe specificata, ma è ancora un scalari normale (e non un riferimento). È necessario utilizzare l'oggetto restituisce se si desidera chiamare metodi:

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

È anche possibile ottenere l'oggetto segreto se hai solo lo scalare legato:

my $secret_object = tied $normal_scalar;

Ho un intero capitolo sul pareggio in Mastering Perl .

Altri suggerimenti

Suggerisco di fare un oggetto normale Perl e quindi sovraccarico in stringa ing. Si perde la capacità di memorizzare un valore mediante assegnazione, ma mantenere la capacità di ottenere il valore dalla stampa l'oggetto. Una volta che si inizia a voler chiamare direttamente i metodi, un oggetto è probabilmente quello che volete.

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;

Esempio di utilizzo:

use Link;

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

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

Se davvero, vuole veramente l'assegnazione di lavorare troppo, è possibile combinare un oggetto normale con in stringa sovraccarico (Link, sopra) con 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;

Esempio di utilizzo:

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

Questo è tutto abbastanza orribile e una lunga strada da percorrere solo per ottenere la dubbia capacità di assegnare a qualcosa che si può anche chiamare i metodi su e anche stampare così com'è. Un oggetto standard URI con in stringa è probabilmente una scommessa migliore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top