我刚刚开始学习领带.我有一个名为Link的类,我想做以下事情:
如果已获取,则返回链接的地址
如果存储,则存储新地址
能够调用它上面的方法
到目前为止,我的代码是:
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第4行调用没有包或对象引用的方法"print_method".
如果我正确理解了它的消息,则$var->print_method
解析print_method
为调用该方法的某个字符串.我如何从tie中受益,还可以将变量用作对象?
编辑:经过实验,我发现如果我在fetch上返回$ self,我可以调用方法,但是,fetch不会返回地址.
编辑2:perl僧侣为我提供了解决方案:捆绑.tied将返回对象VARIABLE的引用.
通过结合我的方法,我可以完成我想要的一切.
领带是这项工作的错误工具.当您需要与普通数据类型相同的接口但希望自定义操作的工作方式时,可以使用tie.由于您想要像标量一样访问和存储字符串,因此tie不会为您做任何事情.
看起来你想要URI模块或它的子类,也许还有一些重载.
如果您确实需要这样做,则需要使用正确的变量.该领带挂接指定到您指定的类的变量,但它仍然是一个正常的标量(而不是引用).如果要调用方法,则必须使用它返回的对象:
my $secret_object = tie my($normal_scalar), 'Tie::Class', @args; $secret_object->print_method;
如果你只有绑定的标量,你也可以获得秘密对象:
my $secret_object = tied $normal_scalar;
我有一整章关于掌握Perl的关系.
我建议制作一个普通的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对象可能是更好的选择.