如何内嵌Perl子例程? [英] How can I inline Perl subroutines?

查看:84
本文介绍了如何内嵌Perl子例程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读 代码完成2 ,其中提到的要点之一是关于为似乎过于简单而无法拥有自己的子例程的操作,以及如何提供帮助.

I am reading Code Complete 2, and one of the points mentioned is about creating subroutines even for operations that seem too simple to have their own subroutines, and how that can be helpful.

我知道我可以使用inline关键字 C和C ++中的内联函数.但是我从未遇到过在Perl中内联子例程的方法.

I know I can inline functions in C and C++ using the inline keyword. But I never came across a way to inline subroutines in Perl.

是否可以告诉Perl解释器内联子例程调用(或为什么不这样做)?

推荐答案

常量子例程(即具有空原型和恒定返回值的子例程)是内联的.这就是常量杂注定义常量的方式:

Constant subroutines, i.e. subroutines with an empty prototype and constant return value, are inline. That is how the constant pragma defines constants:

sub five() { 5 }

如果在首次使用之前可以看到它,将被内联.

would be inlined if it is seen before its first use.

否则,Perl允许在运行时动态重新定义子例程,因此不适合使用内联.

Otherwise, Perl allows subroutines to be dynamically redefined at run time, so inlining is not suitable.

对于总是在给定相同输入的情况下返回相同值的子例程,可以使用记忆化.

For subroutines that always return the same value given the same inputs, you can use memoization.

《 Perl编程》第13章提供了有关perl采取的优化步骤.

Chapter 13 of Programming Perl provides some information on the optimization steps taken by perl.

这称为恒定折叠.恒定折叠不限于简单的情况,例如在编译时将2 ** 10变成1024.它还解析函数调用-满足第6章子例程"中内联常量函数"部分中所定义条件的内置子例程和用户声明的子例程.让人想起FORTRAN编译器对自己的内部函数的臭名昭著的知识,Perl还知道在编译过程中要调用哪个内置函数.这就是为什么如果尝试获取0.0的对数或负数的sqrt会导致编译错误,而不是运行时错误,并且解释器永远不会运行的原因.

This is called constant folding. Constant folding isn't limited to simple cases such as turning 2**10 into 1024 at compile time. It also resolves function calls -- both built-ins and user-declared subroutines that meet the criteria from the section "Inlining Constant Functions" in Chapter 6, Subroutines. Reminiscent of FORTRAN compilers' notorious knowledge of their own intrinsic functions, Perl also knows which of its own built-ins to call during compilation. That's why if you try to take the log of 0.0 or the sqrt of a negative constant, you'll incur a compilation error, not a run-time error, and the interpreter is never run at all.

另请参见 perldoc Perlguts .

您可以看到不断折叠自己的效果:

You can see the effect of constant-folding yourself:

#!/usr/bin/perl

use strict; use warnings;

sub log_ok () { 1 }

if ( log_ok ) {
    warn "log ok\n";
}

perl -MO=Deparse t.pl

输出:

sub log_ok () { 1 }
use warnings;
use strict 'refs';
do {
    warn "log ok\n"
};
t.pl syntax OK

在这里,恒定的折叠导致将if块替换为do块,因为编译器知道log_ok将始终返回真实值.另一方面,使用:

Here, constant folding led to the replacement of the if block with a do block because the compiler knew that log_ok would always return a true value. On the other hand, with:

#!/usr/bin/perl

use strict; use warnings;

sub log_ok () { 0.5 > rand }

if ( log_ok ) {
    warn "log ok\n";
}

缩小输出:

sub log_ok () {
    use warnings;
    use strict 'refs';
    0.5 > rand;
}
use warnings;
use strict 'refs';
if (log_ok) {
    warn "log ok\n";
}
t.pl syntax OK

C编译器可能已将if (log_ok)替换为if ( 0.5 > rand ). perl不会那样做.

A C compiler might have replaced the if (log_ok) with if ( 0.5 > rand ). perl does not do that.

这篇关于如何内嵌Perl子例程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆