与perl builtin同名的package方法

时间:2014-04-02 07:31:27

标签: perl

所以我的模块有一个名为push的方法。在这个方法中,我调用了perl的内置push函数。现在我有另一个名为unshift的方法,在这个方法中,我再次调用perl的内置push函数。

 1 package Deque;
 2 
 3 ...
 4 sub push {
 5   my ($self, $node) = @_;
 6   push @{ $self->{nodes} } => $node;
 7   ...
 8 }
 9
10 sub unshift {
11   my ($self, $node) = @_;
12   push @{ $self->{nodes} } => $node;
13   ...
14 }

程序运行,但我收到此警告Ambiguous call resolved as CORE::push() ... line 12

所以我将第12行更改为CORE::push @{ $self->{nodes} } => $node,并且警告消失了。

为什么perl没有警告我第6行? 有没有更好的方法摆脱警告?我无法更改方法名称。

2 个答案:

答案 0 :(得分:5)

请注意,如果交换子程序,则不会显示任何警告:

sub unshift {
   my ($self, $node) = @_;
   push @{ $self->{nodes} } => $node;
}

sub push {
   my ($self, $node) = @_;
   push @{ $self->{nodes} } => $node;
}

...如果预先声明push,则有两个

sub push;

sub unshift {
   my ($self, $node) = @_;
   push @{ $self->{nodes} } => $node;
}

sub push {
   my ($self, $node) = @_;
   push @{ $self->{nodes} } => $node;
}

# Ambiguous call resolved as CORE::push(), qualify as such or use & at line 10.
# Ambiguous call resolved as CORE::push(), qualify as such or use & at line 15.

我的猜测是,在解析整个子例程的主体之前,基本上不会考虑包中定义的push名称。这就是为什么在子程序中这个调用不被认为是模棱两可的。

尽管如此,我还是假设在perldiag中建议使用CORE::前缀添加所有相应的来电。

  

要将[子例程名称]静默解释为Perl运算符,请使用CORE::前缀   在运算符上(例如CORE::log($x))或将子例程声明为对象方法。

答案 1 :(得分:1)

您可以使用method属性声明该方法,使其免受警告的影响:

sub push :method {
  ...
}

此时它仍可用作对象的方法

$obj->push   # resolves to the method defined above

但常规push作为核心运算符的任何用法都会解析为常规CORE::push

push @array, $more;   # resolves to CORE::push