使用Perl';s方法::签名,为什么可以';我调用对象实例上的方法吗?
我跟着什么 现在,当我尝试调用方法使用Perl';s方法::签名,为什么可以';我调用对象实例上的方法吗?,perl,oop,Perl,Oop,我跟着什么 现在,当我尝试调用方法testScript时,我得到一个错误全局符号$obj需要显式的包名,它无法调用testScriptTwo use strict; use warnings; package Test; use Method::Signatures; method new { my $obj = bless {}, $self; return $obj; } method testScript { $obj->testScriptTw
testScript
时,我得到一个错误全局符号$obj需要显式的包名
,它无法调用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在包本身内调用方法?使用以下方法:
method testScript {
$self->testScriptTwo();
}
第一个参数在变量
$self
中,而不是$obj
您的问题似乎表明您不了解作用域的基本知识以及普通Perl对象的工作原理
在Perl中,当您对包名或引用使用->method
语法时,将调用该包中的子例程method
。子例程的第一个参数是调用方法的对象
所以,如果你这样做了
My::Friend->new('Alfred');
包My::Friend
中的new
子例程接收两个参数My::Friend
和Alfred
在一个新方法中,习惯上将第一个参数称为$class
,但这完全取决于您。如果您愿意,您可以使用$basket\u 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
$ ./zt.pl
36
输出:
Alfred
Alfred derp derp
$ ./zt.pl
36
美元/zt.pl
36好的,您需要回溯一点-您是新的
方法首先被破坏了,这表明您并不真正了解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
创建实例化对象
然后你可以用它来“做事情”——当你使用->
来“调用”一个方法时,子例程中的第一个参数就是对象引用
所以
相当于:
Foo::set_name($new_instance, "myname" );
print Foo::get_name($new_instance);
您可以对$new\u instance
执行操作,这是一种允许您包含代码的神奇散列
Method::Signatures
在您了解OO的基础知识之前基本上是不相关的。但这只是“简单地”扩展模块内的函数,这样就不必提取self/class等
默认情况下,定义为method
的方法自动提供$self
。没有$obj
像您正在使用的那样。这是一个对您new
method来说是局部的变量,在它之外根本不存在 如果我想访问另一个包(父包)中的方法,该怎么办?我使用$self还是$obj?例如:$obj->{parent}->testThree()代码>IFAIK,始终使用$self
$self
是Method::Signatures
自动提供的功能,而不必手动完成。这就是为什么您必须理解我在我的中对非方法签名代码所做的更正。我理解,但我不理解Method::Signatures方式。我返回$obj并使用$obj创建引用,即:$obj->{parent},为什么我不能使用$obj调用其他方法并访问包中的那些引用?但是我可以在调用new()时调用它?“为什么我不能使用$obj调用其他方法…但是我可以在调用new()时调用它?”。。。因为,您不理解由子例程定义创建的词法范围。new
中的词法变量$obj
和您试图在testScript
中使用的全局变量$new
彼此无关。@SinanÜnür:我想您的意思是全局变量$obj
,就像我说的,我理解非方法::签名方式,签名对我来说是新事物,我很难理解如何在其中使用oo。证明您并不真正理解非方法::签名
方式。此外,如果您了解范围,您不会认为您必须在testScript
中将实例变量命名为$obj
,因为您在new
中称它为$obj
。不理解某事是不羞耻的。事实上,理解你不懂的东西是决定你是否能学到东西的最重要因素之一。