这两个 eval 之间的区别是否用常量折叠来解释?
Is the difference between these two evals explained with constant folding?
鉴于这两个 evals 仅更改 Module::FOO()
和 FOO()
。
# Symbols imported, and used locally.
eval qq[
package Foo$num;
Module->import();
my $result = Module::FOO() * Module::FOO();
] or die $@;
# Symbols imported, not used locally referencing parent symbol.
eval qq[
package Foo$num;
Module->import();
my $result = FOO() * FOO();
] or die $@;
为什么顶部块 大大 少 space?脚本和输出转载如下,
脚本
package Module {
use v5.30;
use warnings;
use constant FOO => 42;
use Exporter 'import';
our @EXPORT = ('FOO');
}
package main {
use v5.30;
use autodie;
use warnings;
$|=1;
say "Our PID is $$";
for my $num ( 0..1e5 ) {
eval qq[
package Foo$num;
Module->import();
my $result = Module::FOO() * Module::FOO();
] or die $@;
eval qq[
package Foo$num;
Module->import();
my $result = FOO() * FOO();
] or die $@;
}
say "DONE";
_debug();
}
sub _debug {
open my $fh, "<", "/proc/$$/status";
while ( <$fh> ) {
next unless /Rss/;
print;
}
}
结果
包裹(名称space)合格
RssAnon: 78896 kB
RssFile: 5220 kB
RssShmem: 0 kB
本地进口
RssAnon: 168180 kB
RssFile: 5496 kB
RssShmem: 0 kB
这是 Perl 内部不断折叠的结果。这可以通过 haarg
在 irc.freenode.net/#perl
、
上的以下示例来证明
use strict;
use warnings;
package Module {
use constant FOO => 42;
use Exporter 'import';
our @EXPORT = ('FOO');
}
my $subs = {
loc => sub {
package Foo;
Module->import();
my $result = FOO() * FOO();
},
fq => sub {
package Foo;
Module->import();
my $result = Module::FOO() * Module::FOO();
},
};
use Data::Dumper;
$Data::Dumper::Deparse = $Data::Dumper::Indent = 1;
print Dumper($subs);
这将导致,
$VAR1 = {
'loc' => sub {
package Foo;
use warnings;
use strict;
'Module'->import;
my $result = FOO() * FOO();
},
'fq' => sub {
package Foo;
use warnings;
use strict;
'Module'->import;
my $result = 1764;
}
};
你可以看到其中一个有,
my $result = FOO() * FOO();
而另一个有,
my $result = 1764;
如果在编译器阶段(在子编译的情况下)声明模块并完成导入,或者在字符串评估的情况下执行之前,您都可以获得常量折叠,例如这个
BEGIN {
package Module {
use constant FOO => 42;
use Exporter 'import';
our @EXPORT = ('FOO');
}
package Foo { Module->import() }
}
鉴于这两个 evals 仅更改 Module::FOO()
和 FOO()
。
# Symbols imported, and used locally.
eval qq[
package Foo$num;
Module->import();
my $result = Module::FOO() * Module::FOO();
] or die $@;
# Symbols imported, not used locally referencing parent symbol.
eval qq[
package Foo$num;
Module->import();
my $result = FOO() * FOO();
] or die $@;
为什么顶部块 大大 少 space?脚本和输出转载如下,
脚本
package Module {
use v5.30;
use warnings;
use constant FOO => 42;
use Exporter 'import';
our @EXPORT = ('FOO');
}
package main {
use v5.30;
use autodie;
use warnings;
$|=1;
say "Our PID is $$";
for my $num ( 0..1e5 ) {
eval qq[
package Foo$num;
Module->import();
my $result = Module::FOO() * Module::FOO();
] or die $@;
eval qq[
package Foo$num;
Module->import();
my $result = FOO() * FOO();
] or die $@;
}
say "DONE";
_debug();
}
sub _debug {
open my $fh, "<", "/proc/$$/status";
while ( <$fh> ) {
next unless /Rss/;
print;
}
}
结果
包裹(名称space)合格
RssAnon: 78896 kB
RssFile: 5220 kB
RssShmem: 0 kB
本地进口
RssAnon: 168180 kB
RssFile: 5496 kB
RssShmem: 0 kB
这是 Perl 内部不断折叠的结果。这可以通过 haarg
在 irc.freenode.net/#perl
、
use strict;
use warnings;
package Module {
use constant FOO => 42;
use Exporter 'import';
our @EXPORT = ('FOO');
}
my $subs = {
loc => sub {
package Foo;
Module->import();
my $result = FOO() * FOO();
},
fq => sub {
package Foo;
Module->import();
my $result = Module::FOO() * Module::FOO();
},
};
use Data::Dumper;
$Data::Dumper::Deparse = $Data::Dumper::Indent = 1;
print Dumper($subs);
这将导致,
$VAR1 = {
'loc' => sub {
package Foo;
use warnings;
use strict;
'Module'->import;
my $result = FOO() * FOO();
},
'fq' => sub {
package Foo;
use warnings;
use strict;
'Module'->import;
my $result = 1764;
}
};
你可以看到其中一个有,
my $result = FOO() * FOO();
而另一个有,
my $result = 1764;
如果在编译器阶段(在子编译的情况下)声明模块并完成导入,或者在字符串评估的情况下执行之前,您都可以获得常量折叠,例如这个
BEGIN {
package Module {
use constant FOO => 42;
use Exporter 'import';
our @EXPORT = ('FOO');
}
package Foo { Module->import() }
}