【问题标题】:Perl function name clashPerl 函数名冲突
【发布时间】:2010-09-09 03:43:37
【问题描述】:

我的情况是,我正在使用的模块有一个函数,其名称与我自己模块中的函数名称完全相同。当我尝试在我的模块(OO Perl,所以$self->function)中调用该函数时,它正在从另一个模块调用该函数。

我已经通过重命名我的函数来解决这个问题,但有趣的是,有没有办法从我的模块中显式调用函数?

编辑: 这基本上就是我正在做的事情

package Provider::WTO;

use base qw(Provider); # Provider contains a method called date

use utilities::utils; #not my module so don't blame me for the horrendous name :-)
...
sub _get_location
{
    my $self = shift;
    return $self->date."/some_other_string"; # calls utilities::utils::date()
}

【问题讨论】:

  • 你能告诉我们更多吗?您如何加载其他模块等?
  • 另外,添加use strict; use warnings;会发生什么?

标签: perl function naming


【解决方案1】:

如果名称冲突是由另一个模块的导入引起的,您可以考虑Sub::Import,它允许轻松重命名导入,即使导出模块没有明确支持,或者namespace::autoclean/@987654323 @。

package YourPackage;

use Sub::Import 'Some::Module' => (
    foo => { -as => 'moo' },
); # imports foo as moo

sub foo { # your own foo()
    return moo() * 2; # call Some::Module::foo() as moo()
}

命名空间清理模块仅在导入使用函数遮蔽您的任何方法时才有用,在任何其他情况下都没有:

package YourPackage;

use Some::Module; # imports foo
use Method::Signatures::Simple
use namespace::autoclean; # or use namespace::clean -except => 'meta';

method foo {
    return foo() * 2; # call imported thing as a function
}

method bar {
    return $self->foo; # call own foo() as a method
}

1;

这样,当对 foo() 的函数调用已经绑定到导入时,导入的函数将在编译模块后被删除。稍后,在您的模块运行时,将安装一个名为 foo 的方法。方法解析总是在运行时发生,所以任何对 ->foo 的方法调用都会被解析为你自己的方法。

或者,您始终可以通过函数的完全限定名称调用函数,而不要导入它。

use Some::Module ();
Some::Module::foo();

这也可以对方法进行,完全禁用运行时方法查找:

$obj->Some::Module::foo();

但是,需要这样做通常是糟糕设计的标志,您可能应该退后一步,解释一下您最初是如何让自己陷入这种情况的。

【讨论】:

    【解决方案2】:

    你需要来自违规模块的那个子程序吗?在不了解更多信息的情况下,我认为快速解决方法是明确不使用空导入列表导入它:

     use Interfering::Module ();
    

    如果您需要其他导入的东西,您可以指定您需要的:

     use Interfering::Module qw(sub1 sub2);
    

    如果你想要的导出列表真的很长,你可以排除干扰子程序:

     use Interfering::Module qw(!bad_sub);
    

    如果这些都不起作用,您将不得不对干扰模块进行更多说明。

    【讨论】:

    • 有问题的模块没有定义@EXPORT 或@EXPORT_OK 所以会自动导入每个函数不是吗?
    • 不,通常相反。如果没有@EXPORT,通常不会导入任何内容。它是否使用Exporter?如果它定义了自己的 import() 例程,它就可以为所欲为。当你尝试我的建议时会发生什么?
    • 不,它只是一个 .pm 文件,它定义了一堆函数。即使我只导入我想要的函数(不包括日期),它仍然会调用错误的日期函数。
    • 这个文件是否声明了它自己的包?这会将它的子程序与当前包中的子程序分开。听起来您需要修复该模块才能与其他人一起玩。
    【解决方案3】:

    您确定这发生在方法调用(即 $self->function)而不是常规调用中吗?

    如果是这种情况,那么我能看到的唯一方法是您的模块正在扩展另一个模块,并且您没有定义有问题的方法,并且您要扩展的模块定义了一个与您尝试调用的方法同名的函数。

    在任何情况下,您都不能使用use Foreign::Module () 将违规函数导入您的命名空间。

    如果它是被破坏的常规函数​​调用,您可以将其称为Your::Module->function

    【讨论】:

    • 绝对是方法调用
    • 和评论的其余部分,您是否将这个其他模块用作您的超类?
    • 绝对不是,但你已经唤醒了我的记忆。调用该方法的类是定义该方法的类的后代。这有区别吗?
    • @Pedro 这是一个导入的函数,它隐藏了一个继承的方法。
    • 哦,好吧,我不是这么说的。对不起。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-15
    • 2016-05-03
    • 2020-04-23
    • 2015-02-26
    • 1970-01-01
    • 2016-03-27
    相关资源
    最近更新 更多