在Web :: Scraper的语法中{}的含义是什么?

Gar*_* Li 6 perl

我对Perl语法感到困惑.这是关于Web :: Scraper的一个例子.

my $t = scraper {
    process "li", "list[]" => "TEXT";
};
print ref($tweets), "\n";
Run Code Online (Sandbox Code Playgroud)

输出:

Web::Scraper
Run Code Online (Sandbox Code Playgroud)

我无法理解花括号的含义.如果scraper是一个函数,那么为什么要使用{}而不是()

mob*_*mob 7

Web::Scraper::scraper是一个将另一个函数(或函数引用)作为参数的函数.在此上下文中,{ ... }声明一个匿名子例程,该子例程作为参数传递给函数(在其他上下文中,{ ... }可以声明哈希引用).据推测,该函数将导致您提供的代码在某个时刻执行(如文档所示,在scrape调用函数时).

有一种方法可以调用你之前看过的这样的函数:

# reference to a named function
sub my_scraper_function { process "li", "list[]" => "TEXT" };
scraper \&my_scraper_function;
Run Code Online (Sandbox Code Playgroud)

 

# reference to an anonymous function
my $scraper_function = sub { process "li", "list[]" => "TEXT" }; 
scraper $scraper_function;
Run Code Online (Sandbox Code Playgroud)

 

# using a function name
# sometimes this doesn't work under 'use strict subs'
sub my_scraper_function { process "li", "list[]" => "TEXT" };
scraper 'ThisPackage::my_scraper_function';
Run Code Online (Sandbox Code Playgroud)

您还将看到Perl内置的一些语法和其他常见函数,如:mapgrep:

@square_roots = map { sqrt($_) } 1 .. 100;
Run Code Online (Sandbox Code Playgroud)


Eri*_*rom 7

scraper是一个用(&)原型定义的子程序:

sub scraper (&) {
    my $code_ref = shift;
    ...
    $code_ref->($some_value)
    ...
}
Run Code Online (Sandbox Code Playgroud)

该原型告诉perl以scraper与内置map {...} @listgrep {...} @list构造类似的方式解析用户子例程.封闭在代码{...}括号中传递给函数作为代码参考,并是一样的,如果你写sub {...}.要编写mapgrep样子程序,你可以使用(&@)原型,它告诉Perl期待一个代码块,然后列表.

在这种情况下,(&)原型声明该函数只接受一个参数,具有高优先级,并且该参数必须是一个裸块(解释为coderef),一个文字sub {...}声明或一个前面带有引用/解除引用对的表达式\&{some_expression}.如果表达式是一个简单的标量,你可以写\&$code_ref

虽然您找到的语法scraper {...}最短,但您也可以将其称为scraper sub {...}.

如果您需要传递的值scraper保存在变量中,您可以编写:

scraper \&$code_ref; # where the \& portion asserts that the value is a coderef
Run Code Online (Sandbox Code Playgroud)

命名子例程使用相同的语法:

sub some_sub {...}

scraper \&some_sub;
Run Code Online (Sandbox Code Playgroud)

您可以在perlsub上了解有关Perl子程序选项的更多信息.

最后,关于原型的必要警告.原型经常被新手Perl程序员滥用作为参数验证的一种形式,类似于其他一些语言中的函数签名.由于原型可以指定的上下文(标量与列表)的强加,这种用法很容易出错.参数检查最好在子程序内完成,同时@_根据需要进行解包.原型的使用应保留用于诸如scraper意图创建子程序的情况,该子程序以与perl的内置函数之一类似的方式进行解析.