curry-1.001000/0000755000372100001440000000000013123267411012653 5ustar matthewtuserscurry-1.001000/maint/0000755000372100001440000000000013123267410013762 5ustar matthewtuserscurry-1.001000/maint/Makefile.PL.include0000644000372100001440000000030612023160164017351 0ustar matthewtusersBEGIN { -e 'Distar' or system("git clone git://git.shadowcat.co.uk/p5sagit/Distar.git") } use lib 'Distar/lib'; use Distar; author 'mst - Matt S. Trout (cpan:MSTROUT) '; curry-1.001000/t/0000755000372100001440000000000013123267410013115 5ustar matthewtuserscurry-1.001000/t/curry-packagevar.t0000644000372100001440000000374313123267323016562 0ustar matthewtusersuse strict; use warnings; use Test::More tests => 18; use Scalar::Util qw(weaken); use curry; sub dispose_ok($;$) { weaken(my $copy = $_[0]); fail("variable is not a ref") unless ref $_[0]; undef $_[0]; ok(!defined($copy), $_[1]); } { package Foo; sub new { bless {}, shift } } { # basic behaviour - can we call without args? my $foo = Foo->new; my $called; my $code = $foo->$curry::curry(sub { ok(shift->isa('Foo'), '$curry::curry object is correct class'); ok(!@_, '$curry::curry did not pick up any stray parameters'); ++$called; }); fail('$curry::curry did not give us a coderef') unless ref($code) eq 'CODE'; $code->(); ok($called, 'curried code was called'); undef $foo; $called = 0; $code->(); ok($called, 'curried code executed successfully after original object goes out of scope'); } { # parameter passthrough my $foo = Foo->new; my $called; my $code = $foo->$curry::curry(sub { ok(shift->isa('Foo'), '$curry::curry object is correct class'); is_deeply(\@_, [qw(one two three)], 'curried code had the expected parameters'); ++$called; }); fail('$curry::curry did not give us a coderef') unless ref($code) eq 'CODE'; $code->(qw(one two three)); ok($called, 'curried code was called'); undef $foo; $called = 0; $code->(qw(one two three)); ok($called, 'curried code again executed successfully after original object goes out of scope'); } { # stashed parameters my $foo = Foo->new; my $called; my $code = $foo->$curry::curry(sub { ok(shift->isa('Foo'), '$curry::curry object is correct class'); is_deeply(\@_, [qw(stashed parameters one two three)], 'curried code had the expected parameters'); ++$called; }, qw(stashed parameters)); fail('$curry::curry did not give us a coderef') unless ref($code) eq 'CODE'; $code->(qw(one two three)); ok($called, 'curried code was called'); undef $foo; $called = 0; $code->(qw(one two three)); ok($called, 'curried code again executed successfully after original object goes out of scope'); } done_testing; curry-1.001000/t/curry.t0000644000372100001440000000145312023160121014436 0ustar matthewtusersuse strict; use warnings FATAL => 'all'; use Test::More qw(no_plan); use Scalar::Util qw(weaken); use curry; { package Foo; sub new { bless({}, shift) } sub foo { [@_] } } my $foo = Foo->new; is_deeply($foo->foo(1), [ $foo, 1 ], 'Direct object call'); is_deeply($foo->curry::foo->(1), [ $foo, 1 ], 'Curried object call'); weaken(my $weak_foo = $foo); my $curry = $foo->curry::foo; undef($foo); ok($weak_foo, 'Weakened object kept alive by curry'); undef($curry); ok(!$weak_foo, 'Weakened object dead'); $foo = Foo->new; $curry = $foo->curry::weak::foo; is_deeply($curry->(1), [ $foo, 1 ], 'Curried weak object call'); weaken($weak_foo = $foo); undef($foo); ok(!$weak_foo, 'Weak curry does not keep object alive'); is($curry->(1), undef, 'Weak curry returns undef after object is dead'); curry-1.001000/t/curry-weak-packagevar.t0000644000372100001440000000265213123267323017505 0ustar matthewtusersuse strict; use warnings; use Test::More; use Scalar::Util qw(weaken); use curry::weak; sub dispose_ok($;$) { weaken(my $copy = $_[0]); fail("variable is not a ref") unless ref $_[0]; undef $_[0]; ok(!defined($copy), $_[1]); } { package Foo; sub new { bless {}, shift } } { # basic behaviour - can we call without args? my $foo = Foo->new; my $called; my $code = $foo->$curry::weak(sub { ok(shift->isa('Foo'), '$curry::weak object is correct class'); ok(!@_, '$curry::weak did not pick up any stray parameters on the way in'); ++$called; }); fail('$curry::weak::curry did not give us a coderef') unless ref($code) eq 'CODE'; $code->(); ok($called, 'curried code was called'); dispose_ok($foo, '$foo departs without a fight'); $called = 0; $code->(); ok(!$called, '... and we can still use the coderef as a no-op'); } { # parameter passthrough my $foo = Foo->new; my $called; my $code = $foo->$curry::weak(sub { ok(shift->isa('Foo'), '$curry::weak object is correct class'); is_deeply(\@_, [qw(stashed parameters one two three)], 'args passed as expected'); ++$called; }, qw(stashed parameters)); fail('$curry::weak::curry did not give us a coderef') unless ref($code) eq 'CODE'; $code->(qw(one two three)); ok($called, 'curried code was called'); dispose_ok($foo, '$foo departs without a fight'); $called = 0; $code->(); ok(!$called, '... and we can still use the coderef as a no-op'); } done_testing; curry-1.001000/README0000644000372100001440000000452013123267411013534 0ustar matthewtusersNAME curry - Create automatic curried method call closures for any class or object SYNOPSIS use curry; my $code = $obj->curry::frobnicate('foo'); is equivalent to: my $code = sub { $obj->frobnicate(foo => @_) }; Additionally, use curry::weak; my $code = $obj->curry::weak::frobnicate('foo'); is equivalent to: my $code = do { Scalar::Util::weaken(my $weak_obj = $obj); sub { return unless $weak_obj; # in case it already went away $weak_obj->frobnicate(foo => @_) }; }; If you want to pass a weakened copy of an object to a coderef, use the $weak package variable: use curry::weak; my $code = $self->$curry::weak(sub { my ($self, @args) = @_; print "$self must still be alive, because we were called (with @args)\n"; }, 'xyz'); which is much the same as: my $code = do { my $sub = sub { my ($self, @args) = @_; print "$self must still be alive, because we were called (with @args)\n"; }; Scalar::Util::weaken(my $weak_obj = $self); sub { return unless $weak_obj; # in case it already went away $sub->($weak_obj, 'xyz', @_); } }; There's an equivalent - but somewhat less useful - $curry package variable: use curry; my $code = $self->$curry::curry(sub { my ($self, $var) = @_; print "The stashed value from our ->something method call was $var\n"; }, $self->something('complicated')); Both of these methods can also be used if your scalar is a method name, rather than a coderef. use curry; my $code = $self->$curry::curry($methodname, $self->something('complicated')); RATIONALE How many times have you written sub { $obj->something($some, $args, @_) } or worse still needed to weaken it and had to check and re-check your code to be sure you weren't closing over things the wrong way? Right. That's why I wrote this. AUTHOR mst - Matt S. Trout (cpan:MSTROUT) CONTRIBUTORS None yet - maybe this software is perfect! (ahahahahahahahahaha) COPYRIGHT Copyright (c) 2012 the curry "AUTHOR" and "CONTRIBUTORS" as listed above. LICENSE This library is free software and may be distributed under the same terms as perl itself. curry-1.001000/META.json0000644000372100001440000000174213123267411014300 0ustar matthewtusers{ "abstract" : "Create automatic curried method call closures for any class or object", "author" : [ "mst - Matt S. Trout (cpan:MSTROUT) " ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.2, CPAN::Meta::Converter version 2.150005", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "curry", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "perl" : "5.006" } } }, "release_status" : "stable", "version" : "1.001000", "x_serialization_backend" : "JSON::PP version 2.27300" } curry-1.001000/Makefile.PL0000644000372100001440000000031513123237634014630 0ustar matthewtusersuse strict; use warnings FATAL => 'all'; use ExtUtils::MakeMaker; (do './maint/Makefile.PL.include' or die $@) unless -f 'META.yml'; WriteMakefile( NAME => 'curry', VERSION_FROM => 'lib/curry.pm' ); curry-1.001000/MANIFEST0000644000372100001440000000057613123267411014014 0ustar matthewtusersChanges lib/curry.pm lib/curry/weak.pm maint/Makefile.PL.include Makefile.PL MANIFEST t/curry-packagevar.t t/curry-weak-packagevar.t t/curry.t META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) README README file (added by Distar) curry-1.001000/META.yml0000644000372100001440000000114713123267410014126 0ustar matthewtusers--- abstract: 'Create automatic curried method call closures for any class or object' author: - 'mst - Matt S. Trout (cpan:MSTROUT) ' build_requires: ExtUtils::MakeMaker: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.2, CPAN::Meta::Converter version 2.150005' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: curry no_index: directory: - t - inc requires: perl: '5.006' version: '1.001000' x_serialization_backend: 'CPAN::Meta::YAML version 0.012' curry-1.001000/Changes0000644000372100001440000000021013123267346014146 0ustar matthewtusersRevision history for curry 1.001000 - 2017-06-23 - Support $curry::curry and $curry::weak 1.000000 - 2012-09-09 - Initial release curry-1.001000/lib/0000755000372100001440000000000013123267410013420 5ustar matthewtuserscurry-1.001000/lib/curry/0000755000372100001440000000000013123267410014564 5ustar matthewtuserscurry-1.001000/lib/curry/weak.pm0000644000372100001440000000004512005464554016056 0ustar matthewtuserspackage curry::weak; use curry; 1; curry-1.001000/lib/curry.pm0000644000372100001440000000607313123267344015136 0ustar matthewtuserspackage curry; our $VERSION = '1.001000'; $VERSION = eval $VERSION; our $curry = sub { my ($invocant, $code) = splice @_, 0, 2; my @args = @_; sub { $invocant->$code(@args => @_) } }; sub AUTOLOAD { my $invocant = shift; my ($method) = our $AUTOLOAD =~ /^curry::(.+)$/; my @args = @_; return sub { $invocant->$method(@args => @_); } } package curry::weak; use Scalar::Util (); $curry::weak = sub { my ($invocant, $code) = splice @_, 0, 2; Scalar::Util::weaken($invocant) if Scalar::Util::blessed($invocant); my @args = @_; sub { return unless $invocant; $invocant->$code(@args => @_) } }; sub AUTOLOAD { my $invocant = shift; Scalar::Util::weaken($invocant) if Scalar::Util::blessed($invocant); my ($method) = our $AUTOLOAD =~ /^curry::weak::(.+)$/; my @args = @_; return sub { return unless $invocant; $invocant->$method(@args => @_); } } 1; =head1 NAME curry - Create automatic curried method call closures for any class or object =head1 SYNOPSIS use curry; my $code = $obj->curry::frobnicate('foo'); is equivalent to: my $code = sub { $obj->frobnicate(foo => @_) }; Additionally, use curry::weak; my $code = $obj->curry::weak::frobnicate('foo'); is equivalent to: my $code = do { Scalar::Util::weaken(my $weak_obj = $obj); sub { return unless $weak_obj; # in case it already went away $weak_obj->frobnicate(foo => @_) }; }; If you want to pass a weakened copy of an object to a coderef, use the C< $weak > package variable: use curry::weak; my $code = $self->$curry::weak(sub { my ($self, @args) = @_; print "$self must still be alive, because we were called (with @args)\n"; }, 'xyz'); which is much the same as: my $code = do { my $sub = sub { my ($self, @args) = @_; print "$self must still be alive, because we were called (with @args)\n"; }; Scalar::Util::weaken(my $weak_obj = $self); sub { return unless $weak_obj; # in case it already went away $sub->($weak_obj, 'xyz', @_); } }; There's an equivalent - but somewhat less useful - C< $curry > package variable: use curry; my $code = $self->$curry::curry(sub { my ($self, $var) = @_; print "The stashed value from our ->something method call was $var\n"; }, $self->something('complicated')); Both of these methods can also be used if your scalar is a method name, rather than a coderef. use curry; my $code = $self->$curry::curry($methodname, $self->something('complicated')); =head1 RATIONALE How many times have you written sub { $obj->something($some, $args, @_) } or worse still needed to weaken it and had to check and re-check your code to be sure you weren't closing over things the wrong way? Right. That's why I wrote this. =head1 AUTHOR mst - Matt S. Trout (cpan:MSTROUT) =head1 CONTRIBUTORS None yet - maybe this software is perfect! (ahahahahahahahahaha) =head1 COPYRIGHT Copyright (c) 2012 the curry L and L as listed above. =head1 LICENSE This library is free software and may be distributed under the same terms as perl itself.