Copied below is the docs from a module I've written: Junction.pm
It's inspired by the Junctions described in Perl6.
I'd appreciate any comments, including suitability of the module name, and whether it's lacking any features you think necessary, for the module to be useful.
Junction - Perl6 style Junction operators in Perl5.
my $j = Junction->new;
if ($j->any(@grant) eq 'su') {
...
}
if ($j->all($foo, $bar) >= 10) {
...
}
if ($j->none(@pass) eq 'password') {
...
}
if ($j->one(@answer) == 42) {
...
}
# All methods can also be called on the Class Name
if (Junction->one(@answer) == 42) {
...
}
Inspired by the Perl6 design docs, SEE ALSO.
Returns a stateless Junction object, on which you can call any of the
methods listed below.
my $j = Junction->new;
$j->any;
$j->all;
... which is provided as a short cut to typing:
Junction->any;
Junction->all;
Returns an object which overloads the following operators:
"<", "<=", ">", ">=", "==", "!=",
"lt", "le", "gt", "ge", "eq", "ne",
Returns true only if all arguments test true according to the operator
used.
Returns an object which overloads the following operators:
"<", "<=", ">", ">=", "==", "!=",
"lt", "le", "gt", "ge", "eq", "ne",
Returns true if any argument tests true according to the operator used.
Returns an object which overloads the following operators:
"<", "<=", ">", ">=", "==", "!=",
"lt", "le", "gt", "ge", "eq", "ne",
Returns true only if no argument tests true according to the operator
used.
Returns an object which overloads the following operators:
"<", "<=", ">", ">=", "==", "!=",
"lt", "le", "gt", "ge", "eq", "ne",
Returns true only if one and only one argument tests true according to
the operator used.
None.
Maybe allow the first argument to be a regex object, such that:
$j->all( qr/\d+/, @input )
... matches all following arguments against the regex. Would need to figure
out what to return and how/whether to handle captured values. (Suggestions
welcome).
Submit to the CPAN bugtracker http://rt.cpan.org
http://dev.perl.org/perl6/doc/design/exe/E06.html - ``The Wonderful World
of Junctions''.
Carl Franks
Copyright 2005, Carl Franks. All rights reserved.
This library is free software; you can redistribute it and/or modify it under
the same terms as Perl itself (perlgpl, perlartistic).
Re: RFC: Junction.pm
by dragonchild (Archbishop) on May 02, 2005 at 13:37 UTC
|
What does this do that Quantum::Superpositions doesn't? (I know it's a lot of good syntactic sugar, but you need to elaborate on that in the POD.)
The Perfect is the Enemy of the Good.
| [reply] |
|
| [reply] |
|
| [reply] |
|
Thanks, I'll have to spend a while longer looking through the docs to figure out if it does what I want.
I had searched cpan for 'junction', and got no results. Silly me, I should have known to search for Quantum Superpositions!
| [reply] |
Re: RFC: Junction.pm
by Tanktalus (Canon) on May 02, 2005 at 14:40 UTC
|
if (all(5, 10, 15) > any (3, 8, 12, 20))
{ print "Success!\n" }
Does that work? :-) Also, I'm not sure if you can override =~, but that makes much more sense in perl5 land than allowing a regex or something as a parameter, as long as you're going about all this syntactical sugar anyway:
if (all(@input) =~ /^\d+$/) { print "Got all whole numbers!\n" }
looks much better than:
if (all(qr/^\d+$/, @input)) { ... }
Also, these don't make a lot of sense (to me, anyway) in OO format (and I'm an OO freak!). I'd expect more like:
use Junction qw(any all);
if (any(@list) > 0) { print "we have at least one postive number!\n";
+}
if (all(@list) > 0) { print "even better - they're all positive number
+s!\n"; }
I'm not sure why you need that object anyway. | [reply] [d/l] [select] |
|
Agreed, exporting the subs makes a lot more sense. I originally had only the object interface, because of the way it was built - it should have occured to me to use Exporter once that was no longer needed.
if (all(5, 10, 15) > any (3, 8, 12, 20))
{ print "Success!\n" }
No, that doesn't work. I could make it work, but then it's starting to get into the complexity of Quantum::Superpositions (which I've still to fully read the docs of).
Unfortunately, =~ can't be over-riden: that would be very nice. (And why Damian hasn't released Perl6::SmartMatch, I don't know ;) | [reply] [d/l] [select] |
|
if (all(5, 10, 15) > any (3, 8, 12, 20))
{ print "Success!\n" }
Yes, it does work!
I should have tested before I answered: I realised that of course it would work, as the operators the module used are still overloaded, even when being used inside the module.
if (qr/^\d+$/ == all(@input)) { ... }
The above now works. Note that you need to use a regex object qr// rather than just //, and you also need to use '==' or '!=', not '=~' or '!~'. It isn't ideal, but then you only need to use it if you want to!
btw, I've uploaded this to CPAN as Perl6::Junction.
update: changed the above link, as the cpan indexer hasn't picked it up yet, when you search by module name. | [reply] [d/l] [select] |
Re: RFC: Junction.pm
by fireartist (Chaplain) on May 02, 2005 at 20:44 UTC
|
Hmm, I'm undecided about this. I've had a look over Quantum::Superpositions now, and it's got a lot of cool stuff in it. However, I see my approach as mostly syntactic sugar to replace things like:
if ($param eq 'this' || $param eq 'that'
|| $param eq 'the other') {
...
}
with
if ($param eq any('this', 'that', 'the other') {
...
}
which Quantum::Superpositions seems a bit overkill for.
Taking a hint from hardburn above, I did some benchmarks (below) and there is a significant runtime difference, between using my code and Quantum::Superpositions'.
One feature from Quantum::Superpositions that I think would be worth adding, is
$result = any(1,2,3) * 2;
if ($result == 4) {...}
which would be trivial to add.
Tanktalus asked above about if (all(@x) eq any(@y) {...}. I can see how useful that would be, but would have to experiment to find a way to implement it without getting as big as Q::S, while not making the code too ugly.
Would Junction::Simple be a more fitting name? (I'm very hesitant to claim a top-name space)
Benchmark timings...
$ /usr/bin/perl ./benchmark.pl
all: numeric (few)
Rate Quantum-Superpositions Ju
+nction
Quantum-Superpositions 1842/s --
+ -94%
Junction 30303/s 1545%
+ --
all: numeric (lots)
Rate Quantum-Superpositions Jun
+ction
Quantum-Superpositions 1364/s --
+ -44%
Junction 2433/s 78%
+ --
all: string
Rate Quantum-Superpositions Jun
+ction
Quantum-Superpositions 1689/s --
+ -79%
Junction 8000/s 374%
+ --
any: numeric (few)
Rate Quantum-Superpositions Ju
+nction
Quantum-Superpositions 747/s --
+ -97%
Junction 28571/s 3725%
+ --
any: numeric (lots)
Rate Quantum-Superpositions Jun
+ction
Quantum-Superpositions 37.9/s --
+ -97%
Junction 1429/s 3672%
+ --
any: string
Rate Quantum-Superpositions Jun
+ction
Quantum-Superpositions 317/s --
+ -95%
Junction 6422/s 1928%
+ --
| [reply] [d/l] [select] |
|
Tanktalus asked above about if (all(@x) eq any(@y) {...}. I can see how useful that would be, but would have to experiment to find a way to implement it without getting as big as Q::S, while not making the code too ugly.
Actualy it is not all the difficult. Realy once you have overloaded the operators perl manages most of the extra magic to make that work without bloating your code. The code i linked to before is under 60 lines and handles that as well as embeding different any() and all() objects inside each other. For instance it handles
print "YEA" if all( any(1..5), any(1..10), any(1..20)) > all(2..4); as expected.
/me is still dieing to see how you approached the problem.
| [reply] [d/l] |
|
I've uploaded it to cpan as
Perl6::Junction.
It's implemented more simply than yours (plain subs / no eval), which means that it's more lines of code, but in my benchmarks ran around 500% faster.
See my reply to Tanktalus above, for more details on what it supports.
| [reply] |
|
|
|
|
Re: RFC: Junction.pm
by eric256 (Parson) on May 02, 2005 at 15:54 UTC
|
| [reply] |
|
|