简体   繁体   English

如何在Perl中使用块作为变量名

[英]How to use block as a variable name in Perl

Guys I'm new to Perl and I am now in reference chapter, and this topic confuses me. 伙计我是Perl的新手,我现在正在参考章节,这个主题让我很困惑。 I understand the concept of reference since I know C programming too. 我理解参考的概念,因为我也知道C编程。 In the book I am reading says: 在我正在阅读的书中说:

"Not only can you dereference a simple variable name, you can also dereference the contents of a BLOCK. Anywhere you'd put an alphanumeric identifier as part of a variable or subroutine name, you can replace the identifier with a BLOCK returning a reference of the correct type." “您不仅可以取消引用一个简单的变量名称,还可以取消引用BLOCK的内容。在您将字母数字标识符作为变量或子程序名称的一部分放置的任何地方,您可以使用BLOCK替换标识符,返回引用正确的类型。“

I need an example on this part- "anywhere you'd put an alphanumerc identifier as part of a variable.... you can replace the identifier with a block" - exactly how would that happen? 我需要一个关于这一部分的例子 - “你可以在任何地方放置一个字母数字标识符作为变量的一部分....你可以用一个块替换标识符” - 这究竟是怎么回事?

and this example too: 这个例子也是:

&{ $dispatch{$index} }(1, 2, 3);

Can somebody explain that code. 有人可以解释一下代码。

The quoted paragraph is saying that you're not limited to doing 引用的段落说你不仅限于做

my $handler = $displatch{$type} or die;  # Arbitrary code
my $ref = $handler->();                  # Arbitrary code
my @a = @$ref;

You can also do 你也可以

my @a = @{ my $handler = $displatch{$type} or die; $handler->() };

Same goes for other dereferences. 其他解除引用也是如此。

$BLOCK
$BLOCK[ ... ]
$BLOCK{ ... }
@BLOCK
@BLOCK[ ... ]
@BLOCK{ ... }
%BLOCK
&BLOCK
&BLOCK( ... )
*BLOCK

$index contains the name of a hash key. $index包含哈希键的名称。 %dispatch is the hash with said key. %dispatch是具有所述密钥的散列。 The value associated with that key is a subroutine reference, which &{} dereferences. 与该键关联的值是子例程引用,其中&{}取消引用。 It's invoked with 1, 2, 3 as its arguments. 它以1, 2, 3作为参数调用。

This is a fine enough example, although I would generally write: 这是一个很好的例子,虽然我一般会写:

$dispatch{$index}->(1, 2, 3)
sub sample_function1 {
   ...
}
sub sample_function2 {
   ...
}

%dispatch = ( 'f1' => \&sample_function1,
              'f2' => \&sample_function2 );

$index = <STDIN>;
chomp $index;
&{ $dispatch{$index} }(1, 2, 3);

If the user enters f1 this will call sample_function1(1, 2, 3) , if he enters f2 it will call sample_function2(1, 2, 3) . 如果用户输入f1这将调用sample_function1(1, 2, 3) ,如果他输入f2 ,它将调用sample_function2(1, 2, 3)

What the documentation is explaining is that you since you can write sample_function1(1, 2, 3) , you can replace the function name with a block containing code that returns a function reference. 文档解释的是,由于您可以编写sample_function1(1, 2, 3) ,因此可以使用包含返回函数引用的代码的块替换函数名称。

Take a look at the File::Find . 看看File :: Find You may have even used that before. 您可能以前曾经使用过它。 It's one of the first Perl modules that many Perl programmers ever use. 它是许多Perl程序员使用的第一个Perl模块之一。

The find command takes two arguments: find命令有两个参数:

  • The second (we'll start with the simple one) is a list of directories I want to search. 第二个(我们将从简单的一个开始)是我想要搜索的目录列表。

  • The first argument is a bit trickier -- it's an actual subroutine my find command will use. 第一个参数有点棘手 - 它是我的find命令将使用的实际子例程。 The find command uses that subroutine to determine if a particular element in my directory tree matches the criteria I'm looking for. find命令使用该子例程来确定目录树中的特定元素是否与我正在寻找的条件匹配。 What find does is go through each and every element of my directory tree and passes that element to my subroutine. find是遍历我的目录树的每个元素,并将该元素传递给我的子例程。 It's up to my subroutine to check the element to see if it passes muster. 这取决于我的子程序检查元素是否通过集合。

Let's say I want to find all files in my directory that have the suffix of .txt . 比方说,我想找到我的目录中有后缀的所有文件 .txt In Unix, I could do this: 在Unix中,我可以这样做:

$ find $directory -type f -name "*.txt"

In Perl, I create a subroutine called wanted . 在Perl中,我创建了一个名为wanted的子程序。 The find command will pass to my wanted subroutine an element in my directory via the $_ Perl variable. find命令传递给我wanted通过子程序的元素在我的目录$_ Perl的变量。 I can then test that element to see if it's a file that has a .txt suffix: 然后我可以测试该元素以查看它是否是具有.txt后缀的文件:

sub wanted {
    return unless -f;             #Return unless $_ is a file
    return unless /\.txt$/;       #Return unless that file has a `.txt` suffix
    print "$Find::File::name\n";  #It's a file that ends with .txt. Print it.
}

Now, all I have to do is get my wanted subroutine as the first parameter of my find command: 现在,我所要做的就是将我wanted子程序作为我的find命令的第一个参数:

find ( \&wanted, $directory );

That's all there is to it. 这里的所有都是它的。 A real life example that you will (if you haven't already) run into really soon. 一个真实的例子,你将(如果你还没有)很快就会遇到。 In C programming parlance, the wanted subroutine would be called a Callback routine. 在C编程术语中, wanted子程序将被称为回调例程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM