代码之家  ›  专栏  ›  技术社区  ›  Geo

如何正确调用接受2个子例程引用的子例程?

  •  3
  • Geo  · 技术社区  · 15 年前

    想象一下这个子程序:

    sub test(&&)
    {
        my $cr1 = shift;
        my $cr2 = shift;
        $cr1->();
        $cr2->();
    }
    

    我知道我可以这样称呼它: test(\&sub1,\&sub2) 但是我怎么可以这样称呼它:

    test { print 1 },{ print 2 };
    

    如果我说子例程只取一个 & 比发送块有效。我不知道如何让它与2一起工作。

    如果我试着这样运行它,我会得到:

    Not enough arguments for main::test at script.pl line 38, near "},"
    

    编辑:如果没有 sub ?

    4 回复  |  直到 15 年前
        1
  •  8
  •   bdonlan    15 年前

    您可以这样做:

    test(sub { print 1 }, sub { print 2 });
    
        2
  •  12
  •   ysth    15 年前

    你需要明确地说

    test( sub { print 1 }, sub { print 2 } );
    

    test { print 1 } sub { print 2 };
    

    隐式“sub”只对第一个参数可用。 http://perldoc.perl.org/perlsub.html#Prototypes :

    &需要匿名子例程,如果作为第一个参数传递,则不需要子关键字或后续逗号。

    有些东西在里面用一个额外的词来伪装它:

    test { print 1 } against { print 2 };
    
    sub against (&) { $_[0] }
    sub test (&@) { ... }
    

    但我从来没有那么喜欢过。

        3
  •  1
  •   Paul Tomblin    15 年前

    我的一个程序中有以下代码:

    sub generate($$$$)
    {
        my ($paramRef, $waypointCodeRef, $headerRef,
            $debugCodeRef) = @_;
    ...
       &$headerRef();
    ...
           my $used = &$waypointCodeRef(\%record);
    

    我称之为

    CreateDB::generate(\%param, \&wayPointCode, \&doHeader, \&debugCode);
    
        4
  •  1
  •   draegtun    15 年前

    如果你真的想更多地弯曲语法,那就看看 Devel::Declare

    使用的模块示例 Devel:声明 :

    完整列表 modules on CPAN dependant 在devel上::可以通过以下方式找到declare CPANTS

    以下是示例 Test::Class::Sugar pod :

    use Test::Class::Sugar;
    
    testclass exercises Person {
        # Test::Most has been magically included
    
        startup >> 1 {
            use_ok $test->subject;
        }
    
        test autonaming {
            is ref($test), 'Test::Person';
        }
    
        test the naming of parts {
            is $test->current_method, 'test_the_naming_of_parts';
        }
    
        test multiple assertions >> 2 {
            is ref($test), 'Test::Person';
            is $test->current_method, 'test_multiple_assertions';
        }
    }
    
    Test::Class->runtests;
    


    这里有一些性感的东西 PerlX::MethodCallWithBlock pod :

    use PerlX::MethodCallWithBlock;
    
    Foo->bar(1, 2, 3) {
      say "and a block";
    };
    


    与使用类似源过滤器的方法相比,declare是一种更健壮、更明智的扭曲Perl代码的方法。 Filter::Simple .

    这里是一个 video 从它的作者那里可能会有更多的帮助。

    /I3AZ/