【问题标题】:how to create perl aliases? typeglobs?如何创建 perl 别名?类型球?
【发布时间】:2018-06-25 07:39:53
【问题描述】:

假设我正在处理另一个包中的哈希,并且我想为该变量创建一个别名?有什么干净的方法可以做到这一点?这个示例代码显示了我想要做什么,但是它以及它的十几个变体都出现了故障。

#!/usr/bin/perl
#use strict;  # I want it to work with strict.

my $p = Person->new("Joe");
my $name;
*name = \*$p->{"name"};     # Latest broken attempt

printf("'%s' should eq '%s' because they both point to the same place.\n",
       $name, $p->{"name"});

$name = "Sam";

printf("'%s' should eq '%s' because they both point to the same place.\n",
       $name, $p->{"name"});
exit 0;


package Person;

sub new {
    my $class = shift;

    my $this = {};
    bless $this, $class;

    $this->{"name"} = shift;

    return $this;
}

我想要的功能是能够操作$p->{"name"} 几十次,而不必重复输入$p->{"name"}。真正的数据结构要复杂得多,有很多嵌套的哈希。

这可能很容易。 谢谢。

【问题讨论】:

    标签: perl alias perl-module


    【解决方案1】:

    最简单的方法是制作副本:

    use strict;
    use warnings;
    my $p = { name => "Joe" };
    my $name = $p->{name};
    print "'$name' is '$p->{name}'\n";
    

    如果我不需要分配给$name,我会使用这个。

    如果您希望能够通过$name 进行写作,最简单的方法是使其成为参考:

    use strict;
    use warnings;
    my $p = { name => "Joe" };
    my $name = \$p->{name};
    print "'$$name' is '$p->{name}'\n";
    $$name = "Jill";
    print "'$$name' is '$p->{name}'\n";
    

    如果你真的想要一个别名,最简单的方法是滥用for循环:

    use strict;
    use warnings;
    my $p = { name => "Joe" };
    for my $name ($p->{name}) {
        print "'$name' is '$p->{name}'\n";
        $name = "Jill";
        print "'$name' is '$p->{name}'\n";
    }
    

    如果你的 perl 足够新(5.22+),你也可以通过引用做别名:

    use strict;
    use warnings;
    use feature 'refaliasing';
    my $p = { name => "Joe" };
    \my $name = \$p->{name};
    print "'$name' is '$p->{name}'\n";
    $name = "Jill";
    print "'$name' is '$p->{name}'\n";
    

    最后,您可以通过分配给 typeglob 来对包变量进行别名处理,但这不是我在这里实际使用的东西:

    use strict;
    use warnings;
    my $p = { name => "Joe" };
    *name = \$p->{name};  # sets *name{SCALAR} to point to $p->{name}
    our $name;            # declares $name so we can use it to refer to $main::name
    print "'$name' is '$p->{name}'\n";
    $name = "Jill";
    print "'$name' is '$p->{name}'\n";
    

    【讨论】:

    • 第三种实现别名的方法是使用 Data::Alias。
    • 真的和再别名有什么不同吗?
    • @ikegami 是的,它在 perl 内部做了一些非常可怕的事情。见metacpan.org/pod/Data::Alias#IMPLEMENTATION
    • 如果您想更改语言,您需要实际更改解析器(重新别名)或挂钩(Data::Alias)。这并没有什么不同。
    猜你喜欢
    • 2013-11-14
    • 1970-01-01
    • 2021-03-03
    • 2020-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多