代码之家  ›  专栏  ›  技术社区  ›  Ritwik Bose

如何用Perl编写函数式的代码?

  •  4
  • Ritwik Bose  · 技术社区  · 15 年前

    你是如何做到的:

    1. 有一个 sub 返回A 附属的

    2. 以代码形式执行文本

    在Perl?

    另外,我如何具有匿名函数存储状态?

    4 回复  |  直到 15 年前
        1
  •  16
  •   Ether    15 年前

    Sub返回Sub作为 科德夫 以下内容:

    # example 1: return a sub that is defined inline.
    sub foo
    {
        return sub {
            my $this = shift;
            my @other_params = @_;
    
            do_stuff();
            return $some_value;
        };
    }
    
    # example 2: return a sub that is defined elsewhere.
    sub bar
    {
        return \&foo;
    }
    

    可以使用执行任意文本 eval 功能:参见文档 perldoc -f eval 以下内容:

    eval q{print "hello world!\n"};
    

    注意这是 非常危险 如果您正在评估从用户输入中提取的任何内容,并且通常是一个糟糕的实践,因为您通常可以在coderef中定义代码,如前面的示例所示。

    您可以使用 state variable (在Perl5.10中是新的),或者变量的作用域高于Sub本身,作为 closure :

    use feature 'state';
    sub baz
    {
        state $x;
        return ++$x;
    }
    
    # create a new scope so that $y is not visible to other functions in this package
    {
        my $y;
        sub quux
        {
            return ++$y;
        }
    }
    
        2
  •  7
  •   daotoad    15 年前

    返回子例程引用。

    下面是一个简单的例子,它创建了一个值上关闭的子引用:

    my $add_5_to = add_x_to(5);
    
    print $add_5_to->(7), "\n";
    
    sub add_x_to {
        my $x = shift;
    
       return sub { my $value = shift; return $x + $value; };
    
    }
    

    您还可以使用这样的命名SUB:

    sub op {
        my $name = shift;
    
        return $op eq 'add' ? \&add : sub {};
    }
    
    sub add {
        my $l = shift;
        my $r = shift;
    
        return $l + $r; 
    }
    

    你可以使用 eval 使用任意字符串,但不要这样做。代码很难读取,它重新启动编译,这会减慢所有操作的速度。在少数情况下,字符串eval是作业的最佳工具。任何时候字符串评估似乎是一个好主意,你几乎肯定是更好的另一种方法。

    几乎任何你想用字符串eval做的事情都可以用闭包来实现。

        3
  •  5
  •   Sinan Ünür    15 年前

    通过使用 sub 关键字。返回的Sub将关闭它使用的词法变量:

    #!/usr/bin/perl
    
    use strict; use warnings;
    
    sub mk_count_from_to {
        my ($from, $to) = @_;
        return sub {
            return if $from > $to;
            return $from ++;
        };
    }
    
    my $c = mk_count_from_to(-5, 5);
    
    while ( defined( my $n = $c->() ) ) {
        print "$n\n";
    }
    

    5.10介绍 state variables .

    在Perl执行文本时使用 eval EXPR :

    的返回值 EXPR 就像一个小Perl程序一样被解析和执行。首先解析表达式的值(它本身在标量上下文中确定),如果没有任何错误,则在当前Perl程序的词汇上下文中执行,以便随后保留任何变量设置、子例程和格式定义。请注意,每次 eval 执行

    执行任意字符串 打开巨大的安全漏洞。

        4
  •  5
  •   Michael Carman    15 年前

    您可以创建匿名子例程并通过引用访问它们;当然,可以将此引用分配给标量:

    my $subref = sub { ... code ... }
    

    或从另一个子例程返回

    return sub { ... code ... }
    

    如果需要存储状态,可以使用外部作用域中定义的词法变量创建闭包,如:

    sub create_func {
        my $state;
        return sub { ... code that can refer to $state ... }
    }
    

    您可以用运行代码 eval