Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re^3: using eval or equivalent to automatically generate my statements

by tobyink (Abbot)
on Dec 14, 2012 at 10:22 UTC ( #1008814=note: print w/ replies, xml ) Need Help??


in reply to Re^2: using eval or equivalent to automatically generate my statements
in thread using eval or equivalent to automatically generate my statements

OK, so as not to disappoint...

Introducing Acme::Asplode: it lets you drag your caller's lexical variables kicking and screaming into your sub. Ought to work in Perl 5.12+.

package Acme::Asplode; use 5.012; use strict; use warnings; use Keyword::Simple (); use PadWalker (); use Text::Balanced (); use Carp; sub import { Keyword::Simple::define asplode => sub { my $ref = shift; $$ref =~ s/^\s+//; my $extracted; if ($$ref =~ /^\(/) { $extracted = Text::Balanced::extract_bracketed($$ref) or croak "usage: asplode (VARIABLES);"; $extracted =~ s/(^\(|\)$)//g; } else { ($extracted, $$ref) = ($$ref =~ /^([^;]+)(;.*)$/s) or croak "usage: asplode VARIABLES;"; } (my $globs = $extracted) =~ s/[\$\%\@]/*/g; $$ref = "our($extracted); local($globs) = Acme::Asplode::_call +back(q($extracted));$$ref"; } } sub unimport { Keyword::Simple::undefine asplode => (); } sub _callback { my $vars = shift; $vars =~ s/(^\s*|\s*$)//g; my @vars = split /\s*,\s*/, $vars; my $MY = PadWalker::peek_my(2); my $OUR = PadWalker::peek_our(2); return map { exists $MY->{$_} ? $MY->{$_} : exists $OUR->{$_} ? $OUR->{$_} : croak "asplode($_) failed; caller has no $_ defined"; } @vars; } 'ASPLODE!';

Example usage...

use 5.012; use strict; use warnings; use Acme::Asplode; sub bar { asplode($x, $y); # steal lexical variables from our caller! say $x; say $y; asplode @A, $z; # steal moar lexicals!!! say $z; $z++; # alter our caller's lexical variable!! say for @A; }; sub foo { my $x = 1; my $y = 2; my $z = 3; my @A = qw(a b c); bar(); say "Z is changed: $z"; } foo();

Update: Acme::Asplode, renamed Acme::Lexical::Thief is now on CPAN.

perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'


Comment on Re^3: using eval or equivalent to automatically generate my statements
Select or Download Code

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1008814]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (12)
As of 2015-07-30 18:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (273 votes), past polls