发现 Perl 模块拥有的所有子例程的最佳方法是什么?

发布于 2024-07-14 01:51:42 字数 271 浏览 12 评论 0原文

以编程方式发现 Perl 模块具有的所有子例程的最佳方法是什么? 这可以是一个模块、一个类(无 @EXPORT)或介于两者之间的任何内容。

编辑:下面的所有方法看起来都有效。 我可能会在生产中使用 Class::Sniff 或 Class::Inspector 。 然而,Leon 的答案被标记为“已接受”,因为它回答了所提出的问题,尽管不需要使用严格的“refs”。 :-) Class::Sniff 随着它的进展可能是一个不错的选择; 看来是花了很多心思的。

What's the best way to programatically discover all of the subroutines a perl module has? This could be a module, a class (no @EXPORT), or anything in-between.

Edit: All of the methods below look like they will work. I'd probably use the Class::Sniff or Class::Inspector in production. However, Leon's answer is marked as 'accepted' since it answers the question as posed, even though no strict 'refs' has to be used. :-) Class::Sniff may be a good choice as it progresses; it looks like a lot of thought has gone into it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

掩耳倾听 2024-07-21 01:51:42
sub list_module {
    my $module = shift;
    no strict 'refs';
    return grep { defined &{"$module\::$_"} } keys %{"$module\::"}
}

ETA:如果你想过滤掉导入的子程序,你可以这样做

use B qw/svref_2object/;

sub in_package {
    my ($coderef, $package) = @_;
    my $cv = svref_2object($coderef);
    return if not $cv->isa('B::CV') or $cv->GV->isa('B::SPECIAL');
    return $cv->GV->STASH->NAME eq $package;
}

sub list_module {
    my $module = shift;
    no strict 'refs';
    return grep { defined &{"$module\::$_"} and in_package(\&{*$_}, $module) } keys %{"$module\::"}
}
sub list_module {
    my $module = shift;
    no strict 'refs';
    return grep { defined &{"$module\::$_"} } keys %{"$module\::"}
}

ETA: if you want to filter out imported subroutines, you can do this

use B qw/svref_2object/;

sub in_package {
    my ($coderef, $package) = @_;
    my $cv = svref_2object($coderef);
    return if not $cv->isa('B::CV') or $cv->GV->isa('B::SPECIAL');
    return $cv->GV->STASH->NAME eq $package;
}

sub list_module {
    my $module = shift;
    no strict 'refs';
    return grep { defined &{"$module\::$_"} and in_package(\&{*$_}, $module) } keys %{"$module\::"}
}
爱她像谁 2024-07-21 01:51:42

Class::Inspector

Class::Inspector 允许您获取有关已加载类的信息。 大多数或全部这些信息可以通过其他方式找到,但它们并不总是非常友好,并且通常涉及相对较高水平的 Perl 魔法,或者看起来奇怪和不寻常的代码。 Class::Inspector 试图为这些信息提供一个更简单、更友好的界面...

Class::Inspector:

Class::Inspector allows you to get information about a loaded class. Most or all of this information can be found in other ways, but they aren't always very friendly, and usually involve a relatively high level of Perl wizardry, or strange and unusual looking code. Class::Inspector attempts to provide an easier, more friendly interface to this information...

病女 2024-07-21 01:51:42

看看这个:
Class::Sniff

该界面目前相当临时,并且可能会发生变化。 创建新实例后,调用report方法是最好的选择。 然后,您可以目视检查它以查找潜在的问题:

my $sniff = Class::Sniff->new({class => 'Some::Class'}); 
  打印 $sniff->报告; 
  

该模块试图帮助程序员发现面向对象代码中的“代码味道”。 如果它报告某些内容,并不意味着您的代码是错误的。 这只是意味着您可能需要更仔细地查看代码以查看是否有任何问题。

目前,我们假设 Perl 默认的最左侧、深度优先搜索顺序。 我们将来可能会改变这一点(并且有一个使用 paths 方法的解决方法。稍后会详细介绍)...

Have a look at this:
Class::Sniff

The interface is rather ad-hoc at the moment and is likely to change. After creating a new instance, calling the report method is your best option. You can then visually examine it to look for potential problems:

my $sniff = Class::Sniff->new({class => 'Some::Class'});
print $sniff->report;

This module attempts to help programmers find 'code smells' in the object-oriented code. If it reports something, it does not mean that your code is wrong. It just means that you might want to look at your code a little bit more closely to see if you have any problems.

At the present time, we assume Perl's default left-most, depth-first search order. We may alter this in the future (and there's a work-around with the paths method. More on this later)...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文