[libtype-tiny-perl] 02/27: Eval::TypeTiny should support alias=>0|1 like Eval::Closure hopefully will
Jonas Smedegaard
js at alioth.debian.org
Fri Aug 9 21:13:08 UTC 2013
This is an automated email from the git hooks/post-receive script.
js pushed a commit to branch master
in repository libtype-tiny-perl.
commit 2943b957dff7ff535f60cc05f36fe6fdb94b72ae
Author: Toby Inkster <mail at tobyinkster.co.uk>
Date: Tue Jul 30 10:14:36 2013 +0100
Eval::TypeTiny should support alias=>0|1 like Eval::Closure hopefully will
---
lib/Eval/TypeTiny.pm | 35 ++++++++++++++++++++++++++---------
t/eval.t | 4 ++++
2 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/lib/Eval/TypeTiny.pm b/lib/Eval/TypeTiny.pm
index 69b51f3..9dd8371 100644
--- a/lib/Eval/TypeTiny.pm
+++ b/lib/Eval/TypeTiny.pm
@@ -3,10 +3,17 @@ package Eval::TypeTiny;
use strict;
BEGIN {
- *HAS_LEXICAL_SUBS = ($] >= 5.018) ? sub(){!!1} : sub(){!!0};
- *HAS_LEXICAL_VARS = eval { require Devel::LexAlias } ? sub(){!!1} : sub(){!!0};
+ *HAS_LEXICAL_SUBS = ($] >= 5.018) ? sub(){!!1} : sub(){!!0};
};
+{
+ my $hlv;
+ sub HAS_LEXICAL_VARS () {
+ $hlv = !! eval { require Devel::LexAlias } unless defined $hlv;
+ return $hlv;
+ }
+}
+
sub _clean_eval
{
local $@;
@@ -42,6 +49,7 @@ sub eval_closure
my (%args) = @_;
my $src = ref $args{source} eq "ARRAY" ? join("\n", @{$args{source}}) : $args{source};
+ $args{alias} = 0 unless defined $args{alias};
$args{line} = 1 unless defined $args{line};
$args{description} =~ s/[^\w .:-\[\]\(\)\{\}\']//g if defined $args{description};
$src = qq{#line $args{line} "$args{description}"\n$src} if defined $args{description} && !($^P & 0x10);
@@ -57,16 +65,19 @@ sub eval_closure
# Type::Exception::croak("Expected a variable name and ref; got %s => %s", $k, $args{environment}{$k});
# }
+ my $alias = exists($args{alias}) ? $args{alias} : 0;
my @keys = sort keys %{$args{environment}};
my $i = 0;
my $source = join "\n" => (
"package Eval::TypeTiny::Sandbox$sandbox;",
"sub {",
- map(_make_lexical_assignment($_, $i++), @keys),
+ map(_make_lexical_assignment($_, $i++, $alias), @keys),
$src,
"}",
);
+ _manufacture_ties() if $alias && !HAS_LEXICAL_VARS;
+
my ($compiler, $e) = _clean_eval($source);
if ($e)
{
@@ -81,8 +92,7 @@ sub eval_closure
my $code = $compiler->(@{$args{environment}}{@keys});
- if (HAS_LEXICAL_VARS)
- {
+ if ($alias && HAS_LEXICAL_VARS) {
Devel::LexAlias::lexalias($code, $_, $args{environment}{$_}) for grep !/^\&/, @keys;
}
@@ -92,7 +102,7 @@ sub eval_closure
my $tmp;
sub _make_lexical_assignment
{
- my ($key, $index) = @_;
+ my ($key, $index, $alias) = @_;
my $name = substr($key, 1);
if (HAS_LEXICAL_SUBS and $key =~ /^\&/) {
@@ -105,7 +115,11 @@ sub _make_lexical_assignment
"my sub $name { goto $tmpname };";
}
- if (HAS_LEXICAL_VARS) {
+ if (!$alias) {
+ my $sigil = substr($key, 0, 1);
+ return "my $key = $sigil\{ \$_[$index] };";
+ }
+ elsif (HAS_LEXICAL_VARS) {
return "my $key;";
}
else {
@@ -124,7 +138,7 @@ sub _make_lexical_assignment
}
}
-HAS_LEXICAL_VARS or eval <<'FALLBACK';
+{ my $tie; sub _manufacture_ties { $tie ||= eval <<'FALLBACK'; } }
no warnings qw(void once uninitialized numeric);
{
@@ -214,6 +228,8 @@ no warnings qw(void once uninitialized numeric);
fallback => 1,
;
}
+
+1;
FALLBACK
1;
@@ -261,7 +277,8 @@ Boolean indicating whether Eval::TypeTiny has support for lexical subs.
Don't worry; closing over lexical variables in the closures is always
supported! However, if this constant is true, it means that
L<Devel::LexAlias> is available, which makes them slightly faster than
-the fallback solution which uses tied variables.
+the fallback solution which uses tied variables. (This only makes any
+difference when the C<< alias => 1 >> option is used.)
=back
diff --git a/t/eval.t b/t/eval.t
index ef10af0..9d0eb27 100644
--- a/t/eval.t
+++ b/t/eval.t
@@ -67,6 +67,7 @@ my $external = 40;
my $closure2 = eval_closure(
source => 'sub { $xxx += 2 }',
environment => { '$xxx' => \$external },
+ alias => 1,
);
$closure2->();
@@ -86,6 +87,7 @@ is($external, 42, 'closing over variables really really really works!');
my $closure = eval_closure(
source => 'sub { $$xxx += 2 }',
environment => { '$xxx' => \$number },
+ alias => 1,
);
$closure->();
@@ -119,6 +121,7 @@ is($external, 42, 'closing over variables really really really works!');
my $closure = eval_closure(
source => 'sub { $xxx = $_[0]; tied($xxx)->my_method }',
environment => { '$xxx' => \$var },
+ alias => 1,
);
is($closure->(2), 42, 'can close over tied variables ... AUTOLOAD stuff');
@@ -127,6 +130,7 @@ is($external, 42, 'closing over variables really really really works!');
my $nother_closure = eval_closure(
source => 'sub { tied($xxx)->can(@_) }',
environment => { '$xxx' => \$var },
+ alias => 1,
);
ok( $nother_closure->('my_method'), '... can');
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libtype-tiny-perl.git
More information about the Pkg-perl-cvs-commits
mailing list