是否有某种方法可以像严格一样制作$ a和$ b等变量?

Axe*_*man 5 perl timtowtdi

根据迈克尔卡曼的评论,我决定改写这个问题.请注意,在此编辑之前会出现11条评论,并且相信迈克尔观察到我没有以明确我要求的方式编写问题.


问:什么是标准-或清洁的方法-假的特殊地位是$a$b通过导入模块有关于严格?

首先是一些设置.以下作品:

#!/bin/perl
use strict;
print "\$a=$a\n";
print "\$b=$b\n";
Run Code Online (Sandbox Code Playgroud)

如果我再添加一行:

print "\$c=$c\n";
Run Code Online (Sandbox Code Playgroud)

我在编译时遇到错误,这意味着我的任何令人眼花缭乱的打印代码都无法运行.

如果我评论use strict;它运行正常.在狭窄之外,$a并且$b主要特别在于sort将两个值与这些名称进行比较.

my @reverse_order = sort { $b <=> $a } @unsorted;
Run Code Online (Sandbox Code Playgroud)

因此,主要的功能差异有关$a,并$b此路不通虽然Perl的"知道他们的名字" -是你最好知道这一点,当你排序,或者使用一些功能列表::的Util.

只有当你使用严格,这$a$b在一个全新的方式成为特殊变量.它们是唯一的严格意义上的变量,而不会抱怨它们没有被声明.

:现在,我喜欢严格,但令我感到震惊的是,如果TIMTOWTDI(有多种方法可以做到这一点)是Perl中的规则#1,那么这不是非常TIMTOWDI.它说,$a$b是特殊的,仅此而已.如果你想使用变量,你不必声明$a并且$b是你的家伙.如果你想通过添加三个变量$c,突然之间还有另一种方法可以做到.

没关系在操纵哈希$k并且$v可能更有意义:

my %starts_upper_1_to_25 
    = skim { $k =~ m/^\p{IsUpper}/ && ( 1 <= $v && $v <= 25 ) } %my_hash
;`
Run Code Online (Sandbox Code Playgroud)

现在,我使用,我喜欢严格.但我只想要$k并且$v能够看到skim最紧凑的语法.而且我希望它能够被简单地看到

use Hash::Helper qw<skim>;
Run Code Online (Sandbox Code Playgroud)

我不是要问这个问题,而是要知道如何使它变黑.下面我的"回答",应该让你知道我知道Perl是危险的.我问是否有办法严格接受其他变量,或者什么是最干净的解决方案.答案很可能是否定的.如果是这种情况,它似乎不是非常TIMTOWTDI.

zig*_*don 7

其他人提到了如何"使用变量"和"我们的" - 我只是想补充说$ a和$ b是特殊情况,因为它们在排序例程内部使用.这是strict.pm文档中的注释:

Because of their special use by sort(), the variables $a and $b are 
exempted from this check.
Run Code Online (Sandbox Code Playgroud)


Mic*_*man 2

如果我理解你的问题,你想编写一个模块,在用户的命名空间中声明变量(这样他们就不必这样做),并在回调中自动本地化。是对的吗?

您可以通过声明全局变量并导出它们来做到这一点。(不过请注意,未经要求就导出东西通常被认为是不好的形式。)

package Foo;
use strict;
use warnings;

require Exporter;
our @ISA    = qw(Exporter);
our @EXPORT = qw(*k *v hashmap);
our ($k, $v);

sub hashmap(&\%) {
    my $code = shift;
    my $hash = shift;

    while (local ($k, $v) = each %$hash) {
        $code->();
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:导出的是*k*v,而不是$k$v。如果您不导出整个 typeglob,则用户的包中的localin将无法正常工作。hashmap这样做的副作用是所有各种形式的kand v( %k@v等) 都会被声明和别名。有关此内容的完整说明,请参阅perlmod 中的符号表

然后在你的脚本中:

use Foo; # exports $k and $v

my %h = (a => 1, b => 2, c => 3);

hashmap { print "$k => $v\n" } %h;

__END__
c => 3
a => 1
b => 2
Run Code Online (Sandbox Code Playgroud)