如何使方法成为“最终”方法在 Perl 中?
我想知道是否可以确保我创建的类中的方法不会被猴子修补(猴子修补) 。穆斯能做到这一点吗?
考虑以下几点:
{
package Foo;
sub hello{print "HI"}
1;
}
package main;
sub Foo::hello {print "bye"}
Foo::hello()#bye
I was wondering if it is possible to make sure a method in a class I make will NOT be monkey patched (Monkey patch). Can Moose achieve this?
Consider the following:
{
package Foo;
sub hello{print "HI"}
1;
}
package main;
sub Foo::hello {print "bye"}
Foo::hello()#bye
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
经过快速的网络研究后,我发现 Perlmonks 上的这个线程指出:
我也认为这是不可能的。
使用 Moose,您可以应用方法修饰符允许您定义必须在调用函数之前运行的函数。
我还没有尝试过这个,但也许你可以定义一个函数,
我不知道如何检查它以及它是否有效,但看起来值得一试!
不过我想补充一点,由于 perl 是一种解释语言,任何使用你的包的人都可以查看和编辑源代码,从而可以规避任何预防措施。
After a quick web research i found this thread on Perlmonks that states:
I would also assume that it is impossible.
Using Moose you can apply Method Modifiers that allow you to define functions that must run before a function is called.
I have not tried this but maybe you could define a function
I don't know exactly how to check it and if it even works, but it looks like it's worth a try!
However I would add, that since perl is an interpreted language anyone who uses your package can view and edit the source, making any precaution circumventable.
Perl 不太喜欢
final
子例程的概念,但您可以尝试。给出以下内容:然后您可以编写:
它将打印类似以下内容:
警告是在第一次调用重新定义的子例程之前打印的,而不是在实际重新定义它时打印的(由于 perl 和
Variable::Magic 方式的限制)工作)。但总比没有好。
no warnings;
在那里,因为当重新定义子例程时,perl 通常会抛出警告。因此,也许告诉您的用户使用警告
就足够了。正如拉里所说:Perl doesn't really like the concept of
final
subroutines, but you can try. Given the following:You could then write:
Which will print something like:
The warning is printed right before the redefined subroutine is first called, not when it is actually redefined (due to limitations of the way perl and
Variable::Magic
work). But it is better than nothing.The
no warnings;
is in there since perl will normally throw a warning when subroutines are redefined. So maybe telling your users touse warnings
is good enough. As Larry has said:这是我在问题评论中所写的禁用猴子补丁的解决方案。
结果是 ./final_test.pl 在打印“仍然活着!!!”之前就死掉了。
是的,这使得所有方法“不可修补”,但仍然允许继承/扩展模块。
是的,该模块的用户可以随时更改其酸味或说“无警告”:)
但我们还是大声说“不邀请你!”
也许问题标题应该是“如何在 Perl 中禁用 Monkey Patching?”...
也许通过更多地阅读 perlexwarn 我们甚至可以实现最终的功能......
Here is my solution to disable Monkey Patching as I wrote in the comment to my question.
The result is that ./final_test.pl dies before printing "still living!!!".
Yes this makes all the methods "un-patchable", but still allows the module to be inherited/extended.
And yes user of the module can always change its sours or say "no warnings":)
But still we said loudly "You are not invited!"
Maybe the question title needed to be "How to disable Monkey Patching in Perl?"...
Maybe with more reading of perlexwarn we could implement even a final feature...
致命的重新定义警告会给你你想要的。
但它无法实现语言实现者希望能够优化最终方法调用的优化,例如索引或内联。
由于 p5p 拒绝考虑这种优化可能性(perl6 和 p2 会这样做),
这是不切实际的。但您只需要只读包哈希
%Foo::
及其键即可。方法重定义将引发编译时错误,编译器可以优化方法调用。
我在 github 上有一个分支,它在语言级别上实现了 const,用于词法和包。
https://github.com/rurban/perl/blob /typed/const/pod/perltypes.pod#const
这是计划,但没有支持:
http://blogs.perl.org/users /rurban/2012/09/my-perl5-todo-list.html
所以我分叉了perl5。 http://perl11.org/p2/
Fataling the redefine warnings will give you what you want.
But it will not enable the optimizations a language implementor will want to be able to optimize finalized method calls, such as indexing or inlining.
Since p5p refuses to think about such optimization possibilities (perl6 and p2 does it),
this is not practical. But you simply need to readonly the package hash
%Foo::
and its keys.Method redefinitions will throw compile-time errors then, and the compiler can optimize the method calls.
I have a branch on github which implements const on the language level, for lexicals and packages.
https://github.com/rurban/perl/blob/typed/const/pod/perltypes.pod#const
This was the plan, but there was no support for it:
http://blogs.perl.org/users/rurban/2012/09/my-perl5-todo-list.html
so I forked perl5. http://perl11.org/p2/