我遵循了friedo said here。
现在,当我尝试调用方法testScript
时,我收到错误global symbol $obj requires explicit package name
,但无法调用testScriptTwo
。
use strict;
use warnings;
package Test;
use Method::Signatures;
method new {
my $obj = bless {}, $self;
return $obj;
}
method testScript {
$obj->testScriptTwo(); # Error happens here
}
method testScriptTwo { ... }
测试脚本:
use Test;
my $class = Test->new();
$class->testScript();
如何使用$ obj来调用包本身内的方法?
答案 0 :(得分:4)
请改用:
method testScript {
$self->testScriptTwo();
}
第一个参数位于变量$self
中,而不是$obj
答案 1 :(得分:4)
您的问题似乎表明您不了解范围的基础知识,以及普通Perl对象的工作原理。
在Perl中,当您对包名称或祝福引用使用->method
语法时,将调用该包中的子例程method
。子例程的第一个参数是您调用method
的东西。
所以,如果你这样做
My::Friend->new('Alfred');
包new
中的My::Friend
子例程接收两个参数。 My::Friend
和Alfred
。
在一种新方法中,习惯上将第一个参数称为$class
,但这完全取决于您。如果您愿意,可以使用$basket_case
:
sub new {
my $basket_case = shift;
my $basket = shift;
my $obj = bless { name => $basket } => $basket_case;
return $obj;
}
如果您随后在返回的引用上调用方法,则该方法将接收所述引用作为其第一个参数,允许您访问存储在该引用中的数据:
sub blurb {
my $schmorp = shift;
print $schmorp->{name}, "\n";
return;
}
全部放在一起:
#!/usr/bin/env perl
package My::Package;
use strict;
use warnings;
sub new {
my $basket_case = shift;
my $basket = shift;
my $obj = bless { name => $basket } => $basket_case;
return $obj;
}
sub blurb {
my $schmorp = shift;
print $schmorp->{name}, "\n";
return;
}
sub derp {
my $herp = shift;
printf "%s derp derp\n", $herp->{name};
return;
}
package main;
my $x = My::Package->new('Alfred');
$x->blurb;
$x->derp;
输出:
Alfred Alfred derp derp
您需要了解这些基础知识。在理解底层内容之前,尝试在基础知识之上添加另一层抽象不会使事情变得更容易。
现在,如果你使用Method::Signatures
,按照惯例,它会将隐含的第一个参数放在lexically scoped变量中,默认情况下,它调用$self
。
您可以在特定方法中覆盖该名称,并且在new
中这样做可能是一个好主意,可以传达它不期望对象实例的事实;相反,它返回一个新实例。
无论你在一个sub中调用词法范围的实例变量,都不会影响在另一个sub中调用它的内容。例如:
#!/usr/bin/env perl
use strict;
use warnings;
sub a_number {
my $number = int(rand(10));
return $number;
}
sub square_that_number {
my $x = shift;
return $x * $x;
}
my $bzzzt = a_number();
my $trrrp = square_that_number($bzzzt);
print $trrrp, "\n";
输出:
$ ./zt.pl 36
答案 2 :(得分:2)
好的,你需要回溯一下 - 你的new
方法首先被打破了,这表明你并不真正理解OO的用途。 perl的。
一个非常简单的对象如下所示:
package Foo;
sub new {
#when Foo -> new is called, then 'Foo' is passed in as the class name
my ( $class ) = @_;
#create an empty hash reference - can be anything, but $self is the convention
my $self = {};
#tell perl that $self is a 'Foo' object
bless ( $self, $class );
#return the reference to your `Foo` object
return $self;
}
sub set_name {
my ( $self, $new_name ) = @_;
$self -> {name} = $new_name;
}
sub get_name {
my ( $self ) = @_;
return $self -> {name};
}
当你在代码中调用它时:
use Foo;
my $new_instance = Foo -> new();
将类传递给new
方法,然后使用bless
创建实例化对象。
然后你可以做些什么'有了它 - 当你打电话给'使用->
然后将第一个参数放入子例程的方法是对象引用。
所以
$new_instance -> set_name ( "myname" );
print $new_instance -> get_name();
相当于:
Foo::set_name($new_instance, "myname" );
print Foo::get_name($new_instance);
你对$new_instance
采取行动,这是一种允许你包含代码的神奇哈希。
Method::Signatures
基本上无关紧要。但 所做的只是'简单地说'扩展模块中的功能,这样您就不必提取自我/类等。
默认情况下,定义为method
的方法会自动提供$self
。 没有 $obj
喜欢你正在使用。这是一个对你new
方法而言属于本地的变量,并且根本就不存在于此之外。