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

从Perl中的子例程返回别名

  •  -1
  • tjwrona1992  · 技术社区  · 9 年前

    是否可以从Perl中的子例程返回别名?

    我有一个简单的例子:

    #!/usr/bin/perl
    use warnings;
    use strict;
    use feature qw{ say };
    
    {
        package Test;
        my $value = 'old';
    
        sub get_value {
            return \$value;
        }
    
        sub set_value {
            my ($x) = @_;
            $value = $x;
        }
    }
    
    my $test = Test::get_value();
    say $$test;
    
    Test::set_value('new');
    say $$test;
    

    这基本上是我想要的功能,但是我想找到一种方法 $test 和别名 $value 这样我就可以访问数据而无需取消引用它。这可能吗?


    下面是我想要的语法示例:

    ex(伪码):

    #!/usr/bin/perl
    use warnings;
    use strict;
    use feature qw{ say };
    
    {
        package Test;
        my $value = 'old';
    
        sub get_value {
            # return alias to $value
        }
    
        sub set_value {
            my ($x) = @_;
            $value = $x;
        }
    }
    
    # Gets an alias, NOT a reference
    my $test = Test::get_value();
    
    # Print old
    say $test;
    
    Test::set_value('new');
    
    # Print new
    say $test;
    

    我一直在阅读别名,所有的东西都指向“typeglobs”……但使用typeglob似乎需要使用全局变量,我真的很想避免这种情况。


    此外,我希望一个不需要从CPAN安装任何额外模块的解决方案,因为我需要得到安全部门的批准并让他们安装……这里的任何其他人都希望使用我的脚本。

    1 回复  |  直到 9 年前
        1
  •  2
  •   ikegami Gilles Quénot    9 年前

    首先是一句警告。您正在请求有关执行极差实践的信息。应该消除而不是寻求远距离的行动。


    可以将两个名称绑定到同一个 SV 。这样绑定的名称称为别名。无法返回绑定名称,因此无法返回别名。

    返回一个重载字符串化的对象怎么样?

    $ perl -E'
       use String::Defer qw( );
    
       {
          my $value = "old";
          sub set_value { $value = $_[0] }
          sub get_value { String::Defer->new(\$value) }
       }
    
       {
          my $value = get_value();
          say $value;
          set_value('new');
          say $value;
       }
    '
    old
    new
    

    应该 而是返回一个引用。

    $ perl -E'
       {
          my $value = "old";
          sub set_value { $value = $_[0] }
          sub get_ref { \$value }
       }
    
       {
          my $value_ref = get_ref();
          say $$value_ref;
          set_value('new');
          say $$value_ref;
       }
    '
    old
    new