amo*_*mon 14 perl filehandle method-call
Perl有一个名为像文件句柄字符串被带到特征是一个文件句柄:
# let this be some nice class I wrote
package Input {
sub awesome { ... }
}
Run Code Online (Sandbox Code Playgroud)
因此,当我们做Input->awesome或非常小心:'Input'->awesome,该方法将被调用.除非:
# now somewhere far, far away, in package main, somebody does this:
open Input, "<&", \*STDIN or die $!; # normally we'd open to a file
Run Code Online (Sandbox Code Playgroud)
甚至不必执行此代码,但只有解析器才能看到此代码,以便Perl 'Input'从现在开始将字符串解释为文件句柄.因此,方法调用'Input'->awesome将会死亡,因为表示文件句柄的对象没有很棒的方法.
由于我只控制着我的班级而不是其他代码,我不能简单地决定只在每个地方使用词法文件句柄.
有什么方法可以强制我Input->awesome永远是一个方法调用Input包,但从来没有文件句柄(至少在我控制的范围内)?我认为不应该有任何名称冲突,因为Input包实际上是%Input::藏匿.
完整代码重现问题(另请参阅此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 $@;
Run Code Online (Sandbox Code Playgroud)
示例输出:
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.
Run Code Online (Sandbox Code Playgroud)
对两个不同的东西(使用过的类和文件句柄)使用相同的标识符引发问题.如果您的类是使用在使用文件句柄的代码中使用的其他类,则不会出现错误:
package My1;
use warnings;
use strict;
sub new { bless [], shift }
sub awesome { 'My1'->new }
__PACKAGE__
Run Code Online (Sandbox Code Playgroud)
package My2;
use warnings;
use strict;
use parent 'My1';
sub try {
my $self = shift;
return ('My1'->awesome, $self->awesome);
}
__PACKAGE__
Run Code Online (Sandbox Code Playgroud)
#!/usr/bin/perl
use warnings;
use strict;
use My2;
open My1, '<&', *STDIN;
my $o = 'My2'->new;
print $o->awesome, $o->try;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
391 次 |
| 最近记录: |