autobox-Closure-Attributes

 view release on metacpan or  search on metacpan

META.yml  view on Meta::CPAN

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 )