Я предлагаю создать нормальный объект Perl, а затем перегрузить стр. Вы теряете возможность сохранять значение посредством присваивания, но сохраняете возможность получить значение, печатая объект. Как только вы захотите вызывать методы напрямую, вам, вероятно, нужен объект.
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 со строковым форматированием.