autobox-Closure-Attributes
view release on metacpan or search on metacpan
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: 1.4
name: autobox-Closure-Attributes
no_index:
directory:
- inc
- t
requires:
PadWalker: 0
autobox: '2.40'
resources:
homepage: https://github.com/sartak/autobox-Closure-Attributes/
license: http://dev.perl.org/licenses/
repository: git://github.com/sartak/autobox-Closure-Attributes.git
version: '0.05'
Makefile.PL view on Meta::CPAN
# Load the Module::Install bundled in ./inc/
use inc::Module::Install;
# Define metadata
name 'autobox-Closure-Attributes';
all_from 'lib/autobox/Closure/Attributes.pm';
githubmeta;
requires 'autobox' => '2.40';
requires 'PadWalker';
build_requires 'Test::Exception';
WriteAll;
lib/autobox/Closure/Attributes.pm view on Meta::CPAN
use strict;
use warnings;
use base 'autobox';
our $VERSION = '0.05';
sub import {
shift->SUPER::import(CODE => 'autobox::Closure::Attributes::Methods');
}
package autobox::Closure::Attributes::Methods;
use PadWalker;
sub AUTOLOAD {
my $code = shift;
(my $attr = our $AUTOLOAD) =~ s/.*:://;
# we want the scalar unless the method name already a sigil
$attr = "\$$attr" unless $attr =~ /^[\$\@\%\&\*]/;
my $closed_over = PadWalker::closed_over($code);
exists $closed_over->{$attr}
or Carp::croak "$code does not close over $attr";
my $ref = ref $closed_over->{$attr};
if (@_) {
return @{ $closed_over->{$attr} } = @_ if $ref eq 'ARRAY';
return %{ $closed_over->{$attr} } = @_ if $ref eq 'HASH';
return ${ $closed_over->{$attr} } = shift;
}
lib/autobox/Closure/Attributes.pm view on Meta::CPAN
The effect of L<autobox> is lexical, so you can localize the nastiness to a
particular section of code -- these mysterious closu-jects will revert to their
inert state after L<autobox>'s scope ends.
=head1 HOW DOES IT WORK?
Go ahead and read the source code of this, it's not very long.
L<autobox> lets you call methods on coderefs (or any other scalar).
L<PadWalker> will let you see and change the closed-over variables of a coderef
.
L<AUTOLOAD|perlsub/"Autoloading"> is really just an accessor. It's just harder
to manipulate the "attributes" of a closure-based object than it is for
hash-based objects.
=head1 WHY WOULD YOU DO THIS?
<#moose:jrockway> that reminds me of another thing that might be insteresting:
<#moose:jrockway> sub foo { my $hello = 123; sub { $hello = $_[0] } }; my $closure = foo(); $closure->hello # 123
<#moose:jrockway> basically adding accessors to closures
<#moose:jrockway> very "closures are just classes" or "classes are just closures"
=head1 AUTHOR
Shawn M Moore, C<sartak@gmail.com>
=head1 SEE ALSO
L<autobox>, L<PadWalker>
The L</DESCRIPTION> section is from Anton van Straaten: L<http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html>
=head1 BUGS
my $code = do {
my ($x, $y);
sub { $y }
};
$code->y # ok
t/004-new-capture.t view on Meta::CPAN
sub accgen {
my $n = shift;
return sub { $n += shift || 1 }
}
my $from_3 = accgen(3);
is($from_3->n, 3);
is($from_3->(), 4);
${ PadWalker::closed_over($from_3)->{m} } = 3;
throws_ok { $from_3->m } qr/CODE\(0x[0-9a-fA-F]+\) does not close over \$m at/;
( run in 0.770 second using v1.01-cache-2.11-cpan-05444aca049 )