寻求Perl成语来检查$self是一个类还是一个对象
在Perl中,我被一些看起来像下面的bug的东西咬了一口:
package Foo; sub method { my $self = shift; my @args = @_; ... } 我把它称为子程序,而不是方法: Foo::method( "arg1","arg2" ); 而不是将其称为方法 – 在这种情况下,它是一个“类方法”: Foo->method( "arg1","arg2" ); 调用Foo :: method(“arg1”,“arg2”)导致“arg1”被删除. 使用“对象方法”可能会出现类似的注意事项: my $object = Foo->new(); $obj->method( "arg1","arg2" ); 是否有一个友好,简洁的Perl习惯用于检查第一个参数,通常称为$self,实际上是类(包)中的对象,和/或类/包名? 我想出的最好的是: package Foo; sub method { my $self = ($_[0]->isa(__PACKAGE__) ? shift @_ : die "...error message..."; my @args = @_; ... } 这并不简单 package Foo; sub method { my $self = shift; die "...error message..." if $self->isa(__PACKAGE__); my @args = @_; ... } 要么 package Foo; use Carp::Assert; sub method { my $self = shift; assert($self->isa(__PACKAGE__)); my @args = @_; ... } 笔记: 我知道Perl签名,但不喜欢使用实验性功能. 我知道 我知道穆斯 – 但我不认为穆斯会强制执行. (我错过了什么.) Perl的问题在于有很多方法可以做某事. 解决方法
最好的答案是不要在单个包中混合功能和方法.众所周知,“混合模块”存在问题.您可能希望创建函数的所有内容都应该是类方法调用.
在日常编程中几乎不需要完全限定函数调用. 最简洁的方法是使用Moops,这是使用Moose语法糖的新方法. use Moops; class Foo { method something() { print("something calledn"); } } Foo->new->something(); Foo::something(); # something called # Invocant $self is required at /Users/schwern/tmp/test.plx line 10. Moops is marked as unstable,但这是界面,而不是签名本身.签名已经存在并且可以在生产中使用很长时间,比它们内置的时间更长.更令人担心的是hasn’t been a release in over a year,但是作者写了好东西.你的来电. 否则,与其他任何东西一样,写一个函数. use Carp; use Scalar::Util qw(blessed); sub check_invocant { my $thing = shift; my $caller = caller; if( !defined $thing ) { croak "The invocant is not defined"; } elsif( !ref $thing ) { croak "The invocant is not a reference"; } elsif( !blessed $thing ) { croak "The invocant is not an object"; } elsif( !$thing->isa($caller) ) { croak "The invocant is not a subclass of $caller"; } return $thing; } 由于这会返回调用者并为您处理异常,因此可以非常简洁地使用它. package Foo; sub method { my $self = ::check_invocant(shift); ... } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |