【问题标题】:Reading another packages symbol table in Perl在 Perl 中读取另一个包符号表
【发布时间】:2010-04-17 19:55:10
【问题描述】:

我正在尝试从另一个包中读取全局符号。我将包名称作为字符串。 我正在使用来自Symbol 模块的qualify_to_ref

    my $ref  = qualify_to_ref ( 'myarray', 'Mypackage' ) ;
    my @array =  @$ref ;

给我Not an ARRAY reference at ...... 我想我得到了取消引用的格式错误。

这是一个完整的示例程序。

    use strict;
    use Symbol ;

    package Mypackage ;
    our @myarray = qw/a b/ ;

    package main ;

    my $ref  = qualify_to_ref ( 'myarray', 'Mypackage' ) ;
    my @array =  @$ref ;

【问题讨论】:

    标签: perl typeglob


    【解决方案1】:

    qualify_to_ref 函数返回一个 typeglob 引用,您可以像这样取消引用:

    my @array =  @{*$ref};
    

    typeglob 取消引用语法记录在 here

    【讨论】:

      【解决方案2】:

      您也可以在不使用外部模块的情况下执行此操作,如“符号表”下的 perldoc perlmod 中所述:

      package Mypackage;
      use strict;
      use warnings;
      our @myarray = qw/a b/;
      
      package main;
      
      our @array;
      *array = \@Mypackage::myarray;
      print "array from Mypackage is @array\n";
      

      但是,这是否是一个好主意取决于您的程序的上下文。通常,最好使用访问器方法获取 Mypackage 的值,或者使用 Exporter 将变量导出到您的命名空间。

      【讨论】:

      • 你能修改这个来回答这个问题——“包名在一个字符串中”
      • 对先前评论的改写 - 如果事先知道另一个包,这种方式看起来很好,但如果在运行时指定包名称,我看不出如何使用它。
      【解决方案3】:

      除了 FM 已经提到的方式之外,您还可以通过它的类似哈希的接口访问 typeglob 的特定部分:

      my $array =  *{$ref}{ARRAY};
      

      这可以很方便地找到没有印记的部分,例如IO 部分。我在Mastering Perl 中有一个关于这类东西的章节。

      【讨论】:

        【解决方案4】:

        你需要取消引用它:@$$ref 而不是@$ref

        【讨论】:

        • 为什么讨厌这里?如果你真的测试我的答案,你会发现它有效。
        猜你喜欢
        • 2014-03-30
        • 2021-11-15
        • 2016-02-20
        • 1970-01-01
        • 1970-01-01
        • 2013-05-09
        • 1970-01-01
        • 1970-01-01
        • 2017-09-13
        相关资源
        最近更新 更多