无法通过包找到对象方法,即使我没有使用方法
Can't locate object method via package, even though I'm not using methods
我的代码大致是这样的:
sub define_pattern { push @Internal::patterns, $_[0]; }
package Internal {
our @patterns = ();
sub func { define_pattern { pattern => '(.*)\.c$' }; }
}
Internal::func;
(当然,这是一个简化版!)现在,当我运行它时,它输出:
Can't locate object method "define_pattern" via package "pattern" (perhaps you forgot to load "pattern"?) at x.pl line 6.
我已经用谷歌搜索了这个错误并查看了几个类似的 SO 问题,但是 none 似乎有解决这个问题的方法。为什么 Perl 认为 define_pattern
是方法而 pattern
是包?我认为这个错误只发生在使用 ->
比如 pattern->define_method
.
时
因为子 define_pattern
需要用 ()
调用,这只是一个语法错误,除了间接对象语法启动并试图 运行 它作为在 {}
块内计算的对象上的方法(如 ThisSuitIsBlackNot 的回答中所述)。
但是,我也会适当地更改名称空间,并且您需要限定对 define_pattern
的调用。由于存在包存在于同一个编译单元中的限制,我们将其保留在
use warnings;
use strict;
package Internal;
our @patterns;
sub func {
main::define_pattern ( pattern => qr/(.*)\.c$/ );
}
package main;
Internal::func;
my @array = @Internal::patterns;
print "Copied onto \@array: |@array|\n";
sub define_pattern {
my %in = @_;
push @Internal::patterns, $in{'pattern'};
}
#sub define_pattern { push @Internal::patterns, $_[0]; }
注。需要 Internal::func
调用来触发 define_pattern
的操作,因此对全局 @Internal::patterns
的任何使用都必须在 在 该调用之后进行(在此代码中).所以他们交换了。正则表达式是使用 qr
构建的。 sub 被更改(最小)以便实际将模式存储在全局数组中。代码打印指定的模式:
Copied onto @array: |(?-xism:(.*)\.c$)|
至少能够以最少的更改动态存储模式
package Internal;
our @patterns;
sub func {
my ($arg) = @_;
main::define_pattern ( pattern => qr/$arg/ );
}
package main;
Internal::func('(.*)\.c$/');
你被indirect object syntax咬了。 Perl 对此进行解释:
define_pattern { pattern => '(.*)\.c$' };
作为方法的名称,后跟 returns 调用者的块。您可以使用 indirect
pragma 看到这一点:
no indirect;
sub define_pattern { push @Internal::patterns, $_[0]; }
package Internal {
our @patterns = ();
sub func { define_pattern { pattern => '(.*)\.c$' }; }
}
输出:
Indirect call of method "define_pattern" on a block at foo line 10.
为什么解析器认为 define_pattern
是方法而不是常规子例程?因为 Internal
包中没有名为 define_pattern
的子程序;您在 main
.
中定义了它
如果从另一个包中调用非导出的子程序,则必须使用完全限定的子程序名称:
main::define_pattern({ pattern => '(.*)\.c$' });
(如果在调用之前声明了 define_pattern
,括号是可选的。)
我的代码大致是这样的:
sub define_pattern { push @Internal::patterns, $_[0]; }
package Internal {
our @patterns = ();
sub func { define_pattern { pattern => '(.*)\.c$' }; }
}
Internal::func;
(当然,这是一个简化版!)现在,当我运行它时,它输出:
Can't locate object method "define_pattern" via package "pattern" (perhaps you forgot to load "pattern"?) at x.pl line 6.
我已经用谷歌搜索了这个错误并查看了几个类似的 SO 问题,但是 none 似乎有解决这个问题的方法。为什么 Perl 认为 define_pattern
是方法而 pattern
是包?我认为这个错误只发生在使用 ->
比如 pattern->define_method
.
因为子 define_pattern
需要用 ()
调用,这只是一个语法错误,除了间接对象语法启动并试图 运行 它作为在 {}
块内计算的对象上的方法(如 ThisSuitIsBlackNot 的回答中所述)。
但是,我也会适当地更改名称空间,并且您需要限定对 define_pattern
的调用。由于存在包存在于同一个编译单元中的限制,我们将其保留在
use warnings;
use strict;
package Internal;
our @patterns;
sub func {
main::define_pattern ( pattern => qr/(.*)\.c$/ );
}
package main;
Internal::func;
my @array = @Internal::patterns;
print "Copied onto \@array: |@array|\n";
sub define_pattern {
my %in = @_;
push @Internal::patterns, $in{'pattern'};
}
#sub define_pattern { push @Internal::patterns, $_[0]; }
注。需要 Internal::func
调用来触发 define_pattern
的操作,因此对全局 @Internal::patterns
的任何使用都必须在 在 该调用之后进行(在此代码中).所以他们交换了。正则表达式是使用 qr
构建的。 sub 被更改(最小)以便实际将模式存储在全局数组中。代码打印指定的模式:
Copied onto @array: |(?-xism:(.*)\.c$)|
至少能够以最少的更改动态存储模式
package Internal;
our @patterns;
sub func {
my ($arg) = @_;
main::define_pattern ( pattern => qr/$arg/ );
}
package main;
Internal::func('(.*)\.c$/');
你被indirect object syntax咬了。 Perl 对此进行解释:
define_pattern { pattern => '(.*)\.c$' };
作为方法的名称,后跟 returns 调用者的块。您可以使用 indirect
pragma 看到这一点:
no indirect;
sub define_pattern { push @Internal::patterns, $_[0]; }
package Internal {
our @patterns = ();
sub func { define_pattern { pattern => '(.*)\.c$' }; }
}
输出:
Indirect call of method "define_pattern" on a block at foo line 10.
为什么解析器认为 define_pattern
是方法而不是常规子例程?因为 Internal
包中没有名为 define_pattern
的子程序;您在 main
.
如果从另一个包中调用非导出的子程序,则必须使用完全限定的子程序名称:
main::define_pattern({ pattern => '(.*)\.c$' });
(如果在调用之前声明了 define_pattern
,括号是可选的。)