in reply to Re^5: RFC: Junction.pm
in thread RFC: Junction.pm

The @{} lets you do my $large = any(1..10) > 5;my @large = @{$large}; That is why I don't short circuit. The stringification is something i went back and forth on. It might fit better as any(1..10)->string; but I dunno.

BTW I added in the arthimitic. The nice thing about the dynamic way I overload is that it was only a few extra lines of code.

my $mix = all(1..5) + any(1,2); produces a result like my $mix = all(any(2,3),any(3,4), any(4,5),any(5,6), any(6,7));

Operator overloading realy is magic. ;) I also added a regex ->match method which alls things like if (any(@strings)->match(all($regex))

package List::Junctions; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(none any all); use strict; use vars qw/ $comparisons $compute/; use overload ( '@{}', sub { my $this = shift; return $this->{data}; }, '""', sub { my $this = shift; return join($" , @{$this->{data}}) if $this->{type} e +q 'all'; return $this->{data}->[rand @{$this->{data}}] if $thi +s->{type} eq 'any'; return ''; }, 'bool', sub {my $this = shift; return $this->{bool}; } ); my @bins = qw(binary 3way_comparison num_comparison str_comparison); foreach my $op (split " ", "@overload::ops{ @bins }") { $comparisons->{$op} = eval "sub { return shift() $op shift() }"; eval "use overload '$op' => sub {compare( '$op', \@_) };"; }; @bins = qw(with_assign); foreach my $op (split " ", "@overload::ops{ @bins }") { $compute->{$op} = eval "sub { return shift() $op shift() }"; eval "use overload '$op' => sub { compute( '$op', \@_) };"; }; $comparisons->{regex} = sub { return regex(@_) }; sub new { my $class = shift; my $type = shift || 'any'; return bless { type => $type , data => [@_], }, $class; } sub any { __PACKAGE__->new('any',@_); } sub all { __PACKAGE__->new('all',@_); } sub none { __PACKAGE__->new('none',@_); } sub true { $_[0]->{bool} = 1; $_[0]; } sub false { $_[0]->{bool} = 0; $_[0]; } sub match { compare("regex",@_); } sub compare { my ($how,$self,$compare, $reverse) = @_; my ($true,$false) = (all()->true(), all()->false()); foreach my $item (@{$self->{data}}) { my $test = $reverse ? $comparisons->{$how}->($compare,$item) : $comparisons->{$how}->($item,$compare); if ($test) { push @{$true->{data}} , $item; } else { push @{$false->{data}}, $item; } } return $true if (($self->{type} eq 'none') && scalar @{$true} == +0) or (($self->{type} eq 'all') && scalar @{$false} == +0) or (($self->{type} eq 'any') && scalar @{$true} != +0); return $false; } sub compute { my ($how,$self,$compare, $reverse) = @_; my $new = __PACKAGE__->new($self->{type}); foreach my $item (@{$self->{data}}) { my $new_item = $reverse ? $compute->{$how}->($compare,$item) : $compute->{$how}->($item,$compare); push @{$new->{data}}, $new_item; + } return $new; } sub regex { my ($item,$comparison) = @_; if (ref($item) eq __PACKAGE__) { return $item->match($comparison); } elsif ( ref($comparison) eq __PACKAGE__) { return $comparison->match($item,1); } else { return $item =~ $comparison; } } 1;

___________
Eric Hodges

Replies are listed 'Best First'.
Re^7: RFC: Junction.pm
by dragonchild (Archbishop) on May 04, 2005 at 15:18 UTC
    P6 also has 'one'.
    return $true if (($self->{type} eq 'none') && scalar @{$true} == +0) or (($self->{type} eq 'all') && scalar @{$false} == +0) or (($self->{type} eq 'any') && scalar @{$true} != +0) or (($self->{type} eq 'one') && scalar @{$true} == +1);

    Also, @EXPORT should become @EXPORT_OK. I may want to import all(), but I already have an any() I don't want you to clobber.

    Lastly - you gonna release this or attempt to patch Perl6::Junction? The number of tests for this is going to be quite ... impressive. :-)


    • In general, if you think something isn't in Perl, try it out, because it usually is. :-)
    • "What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?"

      Yea I can add a one function. There was some reason I didn't but I can't remember it now. ;) Might have been an older version of the code and yea I did intend to fix the export stuff and release it. Now I don't realy want to release it because his code does the same thing in the end, but they are drasticaly different code wise (and of course I'm quite fond of my own way ;) ). So wadda think? Release a second one that does almost the same thing? Or just keep it as my pet project on PerlMonks? Is there any harm to me releaseing a seperate but similar module just so that I can get experience with module releases?


      ___________
      Eric Hodges

        There's no harm in releasing your own module, but I'd certainly welcome a patch to Perl6::Junction.

        I was planning on using a startup-eval method to add the arithmetic operators, similar to yours but creating a 'real' subroutine rather than a sub-ref in a hash. What's holding me up though, is getting the time to write the tests, which as dragonchild suggested, is no small task.

        (If you do wish to contribute, including tests would be good :)

        TheDamian has just sent me an implementation of Perl6::Junctions that he had already coded and hadn't done anything with.

        It contains a lot more features from the Perl6 spec, and has some fun code that I'm sure you'll like.

        Could I maybe suggest you hold off releasing your own for now, I'll try and get Damian's code into the Perl6::Junction distribution as soon as I can, and then see what you think?