- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Perl 有点过于宽容:如果您将额外的参数传递给 sub
,它们将被忽略。
为了避免这种情况,我想使用原型(prototype)来确保为每个 sub
提供正确数量的参数。
只要我在使用它之前声明原型(prototype)就可以正常工作:
sub mysub($);
sub mysub2($);
mysub(8);
mysub(8,2); # Complain here
sub mysub($) {
mysub2($@);
}
sub mysub2($) {
if($_[0] == 1) {
mysub(2);
}
print $@;
}
但我真的很讨厌把它分开。我更希望 Perl 阅读完整的文件以查看是否还有进一步的声明。所以我想写这样的东西:
use prototypes_further_down; # This does not work
mysub(8);
mysub(8,2); # Complain here
sub mysub($) {
mysub2($@);
}
sub mysub2($) {
if($_[0] == 1) {
mysub(2);
}
print $@;
}
我能以某种方式要求 Perl 这样做吗?
最佳答案
To avoid this I would like to use prototypes to make sure each
sub
is given the correct amount of arguments.
不,你不会。尽管名称相似,Perl 原型(prototype)不是你父亲的函数原型(prototype)。引用 The Problem with Prototypes (强调我的),
Perl 5's prototypes serve two purposes. First, they're hints to the parser to change the way it parses subroutines and their arguments. Second, they change the way Perl 5 handles arguments to those subroutines when it executes them. A common novice mistake is to assume that they serve the same language purpose as subroutine signatures in other languages. This is not true.
除了它们没有相同的预期目的之外,绕过原型(prototype)是微不足道的,因此它们没有提供实际保护来防止有人故意以(您认为的)“错误”方式调用您的代码。作为perldoc perlsub
告诉我们,
The function declaration must be visible at compile time. The prototype affects only interpretation of new-style calls to the function, where new-style is defined as not using the
&
character. In other words, if you call it like a built-in function, then it behaves like a built-in function. If you call it like an old-fashioned subroutine, then it behaves like an old-fashioned subroutine. It naturally falls out from this rule that prototypes have no influence on subroutine references like\&foo
or on indirect subroutine calls like&{$subref}
or$subref->()
.Method calls are not influenced by prototypes either, because the function to be called is indeterminate at compile time, since the exact code called depends on inheritance.
即使您可以让它提示 mysub(8,2)
、&mysub(8,2)
或 $subref =\&mysub; $subref->(8,2)
或(如果 mysub
是 package MyModule
中的对象方法)$o = MyModule->new; $o->mysub(8,2)
将毫无怨言地工作。
如果您想使用核心 Perl(5.20 之前的版本)验证您的子程序是如何被调用的,那么您需要自己在子程序的主体中执行验证。 Perl 5.20 和更新版本有一个(在撰写本文时为“实验性”)Signatures sub declarations 的扩展可能对你有用,但我自己从未使用过,所以我不能说它的有效性或局限性。还有很多CPAN可用于处理此类事情的模块,您可以通过搜索“签名”或“原型(prototype)”等内容来找到它们。
无论您选择哪种方法,除非您在使用这些签名之前定义这些签名,否则您将无法获得有关不正确函数签名的编译时错误。在您的示例中,两个 sub 相互调用的情况下,这可以通过使用前向声明预先建立其签名来实现:
sub mysub($foo); # Forward declaration
sub mysub2 { mysub(8) }
sub mysub { mysub2('infinite loops ftw!') } # Complete version of the code
关于perl - 让 perl 向前看子原型(prototype),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53975033/
以下代码,我使用 chrome 浏览器控制台进行了检查: function A(){ this.a='a' } 这是一个构造函数。我已经将一个属性 b 赋给了 A 的原型(prototype)。
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 提供事实和引用来回答它. 5年前关闭。 Improve this
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 提供事实和引用来回答它. 3年前关闭。 Improve this
我已经开始阅读 The Pragmatic Programmer,我很喜欢并学习堆形式,但我很难理解示踪子弹和原型(prototype)之间的区别。跟踪项目符号是否像拥有应用程序的所有 View 但尚
尽管阅读了 StackOverflow 上的大多数文章,但我现在实际上对原型(prototype)非常困惑。 function Foo() { } Foo.prototype.speak = func
我正在阅读以下代码,并开始想知道 Rectangle.prototype = Object.create(Shape.prototype) 和 Rectangle.prototype = Shape.
我想知道它们之间的区别: childObj.prototype = Object.create(parentObj.prototype) 和 childObj.prototype = parentOb
这个问题在这里已经有了答案: Why wouldn't I use Child.prototype = Parent.Prototype rather than Child.prototype =
在 node.js 中导出原型(prototype)的首选方法是什么?您可以采用两种方法: 导出原型(prototype)本身 function A () { } module.exports = A
我正在学习 JavaScript,发现了两种分配原型(prototype)的方法。 第一个是A.prototype = B.prototype,第二个是A.prototype = new B() 例如
在一些构造函数的定义之后,例如 child ,我见过以下两种形式: Child.prototype = Parent.prototype; 或 Child.prototype = new Parent
我正在阅读一本关于 OOP javascript 的书,但被其中一个示例卡住了。 在示例代码的第一个版本中,Shape 的一个新实例构造函数被创建并且 toString方法被调用。 toString方
这个问题在这里已经有了答案: What should I connect to the child prototype property in JavaScript (2 个答案) 关闭 8 年前。
在进行原型(prototype)设计时,您在多大程度上放弃了最佳实践来支持代码和修复黑客攻击?当然,代码并不打算在完整的生产环境中保留。 补充:我正在研究一个用 Python 制作的相当大的半工作原型
我正在尝试使用 Prototype 更新隐藏表单字段的值。表单域: 我正在尝试使用原型(prototype)更新值: var additionalVal = ',2'; var itemId = $
我正在阅读How to Make a Javascript Library我发现了作者所说的一个观点: function _() { //Some obects and var
我想用一个新函数扩展“Number”类型,因此我必须定义一个原型(prototype)。当我想到这一点时,我得到了一堆问题: Number 是否既继承了 Object.prototype 又继承了 F
这里好像有区别... 假设我们有 function MyConstructor() {} MyConstructor 的[[Prototype]] 是Function.prototype,不是 MyC
有人建议 Derived.prototype = Object.create(Base.prototype); 优于 Derived.prototype = new Base(); (如 this S
我是一名优秀的程序员,十分优秀!