perl回调

下面是随手写了一个简单的列子,看上去比较分离而且绕的调用方式

#!/usr/bin/perl -w

sub foo {
    my ($a, $b, $out) = @_;
    if ($a > $b){
        $out->($a, $b);
    }
    else {
        $out->($b, $a);
    }
}

sub output {
    my ($a, $b) = @_;
    print “$a > $b\n”;
}

foo(1, 3, \&output);

最终执行的函数是最后一行,调用过程大概就是函数名output作为参数传到foo里,然后if和else里根据判断来执行output这个函数,最后打印信息

表达式\&output生成了一个代码引用code reference,即一个表示该函数的标量,可以像别的标量一样在一个标量变量中保存代码引用,或者像别的标量一样作为一个参数传递,还可以使用这个引用执行它表示的函数,所以就出现了上面的累死下面的语句:

$code_reference->(arguments …);

就像C里传递一个地址,然后通过指针遍历结构体的步骤类似

这里foo里的代码引用参数就称为回调,因为他是由foo的主调者提供的函数,在foo需要帮助时回调他;而foo函数体里的参数$out也称为吊钩hook,因为他提供了一个地方以供额外的功能可以被容易地吊着

这种方法重点在于通过把函数的部分功能参数化成调用其他函数,而不是固定其行为,可以使函数更灵活,这增加的灵活性会在想要函数做些改变时带来好处,例如,执行一次自动的自我检查,不是用许多可选的自测代码把函数弄乱,而是把测试部分与主算法分离,在简洁明了的前提下,能在运行时通过传递不同的代码引用参数使用或者不使用自测代码

发表回复