perl – 防止字符串被解释为文件句柄

Perl具有以文件句柄命名的字符串作为文件句柄的功能
# let this be some nice class I wrote
package Input {
    sub awesome { ... }
}

所以当我们做输入 – >真棒或非常小心:’输入’ – >真棒,该方法将被调用.除非:

# Now somewhere far,far away,in package main,somebody does this:
open Input,"<&",\*STDIN or die $!;  # normally we'd open to a file

这个代码甚至不必被执行,但是只有解析器才能看到Perl从现在开始将字符串“Input”解释为文件句柄.因此,一个方法调用’Input’ – > awesome将会死,因为表示文件句柄的对象没有真棒的方法.

由于我只能控制我的课程,而是控制其他代码,我不能简单地决定只使用各种词法文件句柄.

有没有什么办法可以强制Input-> awesome永远是一个方法调用输入包,但从来没有一个文件句柄(至少在我控制的范围)?我认为不应该有任何名称冲突,因为输入包实际上是%Input :: stash.

完整的代码重现问题(另见这ideone):

use strict;
use warnings;
use feature 'say';

say "This is perl $^V";

package Input {
    sub awesome {
        say "yay,this works";
    }
}

# this works
'Input'->awesome;

# the "open" is parsed,but not actually executed
eval <<'END';
    sub red_herring {
        open Input,\*STDIN or die $!;
    }
END
say "eval Failed: $@" if $@;

# this will die
eval {
    'Input'->awesome;
};
say "Caught: $@" if $@;

示例输出

This is perl v5.16.2
yay,this works
Caught: Can't locate object method "awesome" via package "IO::File" at prog.pl line 27.

解决方法

对于两个不同的东西(一个使用的类和文件句柄)使用相同的标识符就会出现问题.如果您的类是从使用文件句柄的代码中使用的另一个类使用的,那么该错误不会出现:

My1.pm

package My1;

use warnings;
use strict;

sub new { bless [],shift }
sub awesome { 'My1'->new }

__PACKAGE__

My2.pm

package My2;

use warnings;
use strict;
use parent 'My1';

sub try {
    my $self = shift;
    return ('My1'->awesome,$self->awesome);
}

__PACKAGE__

script.pl

#!/usr/bin/perl
use warnings;
use strict;

use My2;
open My1,'<&',*STDIN;
my $o = 'My2'->new;
print $o->awesome,$o->try;

相关文章

1. 如何去重 #!/usr/bin/perl use strict; my %hash; while(...
最近写了一个perl脚本,实现的功能是将表格中其中两列的数据...
表的数据字典格式如下:如果手动写MySQL建表语句,确认麻烦,...
巡检类工作经常会出具日报,最近在原有日报的基础上又新增了...
在实际生产环境中,常常需要从后台日志中截取报文,报文的形...
最近写的一个perl程序,通过关键词匹配统计其出现的频率,让...