Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl-如何在子类中创建方法别名?_Perl_Class - Fatal编程技术网

Perl-如何在子类中创建方法别名?

Perl-如何在子类中创建方法别名?,perl,class,Perl,Class,我试图在子类中创建一个超级类泛型方法的别名,但它似乎不起作用。这个技巧在同一个类中有效,但在超级/子转换中似乎不起作用。下面是一个真实的基本示例。前两个电话有效。第三个调用生成关于未定义子例程的错误。我也尝试过使用SUPER::cat,但也不起作用 package foo; sub cat{ print("inside foo\n"); } *bird = \&cat; package bar; use base 'foo'; *dog = \&cat; pack

我试图在子类中创建一个超级类泛型方法的别名,但它似乎不起作用。这个技巧在同一个类中有效,但在超级/子转换中似乎不起作用。下面是一个真实的基本示例。前两个电话有效。第三个调用生成关于未定义子例程的错误。我也尝试过使用SUPER::cat,但也不起作用

package foo;

sub cat{
  print("inside foo\n");
}

*bird = \&cat;

package bar;

use base 'foo';

*dog = \&cat;

package main;

foo::cat();
foo::bird();
bar::dog();
这:

应该是:

*dog = \&foo::cat;

您混淆了面向对象继承和简单符号导入

正如您所说的,
使用基'foo'
声明了一个超类。这意味着将检查
foo
中是否存在对
bar
中未显示的方法的调用

但是,
*dog=\&cat
不是一个方法调用:它只是一个全局赋值,因此搜索不会超出
&bar::cat

如果您编写的是真正面向对象的代码,那么像这样分配给
*bar::dog
将破坏继承机制的作用

要观察Perl的面向对象功能,请将glob赋值移动到
foo
(这里它只是给一个方法添加别名),并使用方法调用语法进行调用

在这段代码中,
bar
没有自己的方法,它继承了
foo
的所有内容,但代码仍按预期工作

package foo;

sub cat {
  print("inside foo\n");
}

*bird = \&cat;
*dog = \&cat;


package bar;

use base 'foo';



package main;

bar->cat();
bar->bird();
bar->dog();
输出

inside foo
inside foo
inside foo
你应该写

sub dog { shift->cat(@_) }

(基本上是转换
cat
方法)而不是使用glob赋值,这样
bar
的子类可以覆盖或扩展
cat
,而不会破坏
bar
的契约,即
cat
dog
做同样的事情。

将Borodin的思想进一步介绍,假设您正在执行正确的OO,但确实希望父类提供的方法有一个别名,并且只在这个子类(以及更深层的子类)中。在这种情况下,您可能需要:

#!/usr/bin/env perl

package foo;

sub new { return bless {}, shift }

sub cat{
  print("inside foo\n");
}

*bird = \&cat;

package bar;

use base 'foo';

sub dog { $_[0]->can('cat')->(@_) }

package main;

my $bar = bar->new;
$bar->cat();
$bar->bird();
$bar->dog();

此机制在堆栈跟踪中保留
dog
。如果您不想这样做,您可以使用
goto&sub
表单,但由于您只有在知道原因的情况下才应该这样做,因此我不打算在这里举一个例子。

这确实有效。我只是不清楚我为什么需要它。“use base”不应该将所有父方法导入我的子类吗?“use base”与基类+1建立ISA关系:我的评论变成了自己的答案:
#!/usr/bin/env perl

package foo;

sub new { return bless {}, shift }

sub cat{
  print("inside foo\n");
}

*bird = \&cat;

package bar;

use base 'foo';

sub dog { $_[0]->can('cat')->(@_) }

package main;

my $bar = bar->new;
$bar->cat();
$bar->bird();
$bar->dog();