Decision::ParseTree - Replacing waterfall IF-ELSIF-ELSE blocks
Version 0.041
Death to long if-elsif-else blocks that are hard to maintain, and hard to explain to your manager. Heres an overly simplistic example:
if ( $obj->is_numeric ) { if ( $obj->is_positive ) { print 'Positive Number'; } elsif ( $obj->is_negative ) print 'Negative Number'; } else { print 'Looks like zero'; } else { print 'Non-Numeric Value'; }
--- - is_num : 0 : Non-Numeric Value 1 : - is_pos : 1 : Positive Number - is_neg : = : Looks like zero 1 : Negative Number ...
package Rules; use Scalar::Util; sub is_num { my ( $self, $obj ) = @_; return (Scalar::Util::looks_like_number($obj->{value})) ? 1 : 0; } sub is_pos { my ( $self, $obj ) = @_; return ($obj->{value} > 0 ) ? 1 : 0; } sub is_neg { my ( $self, $obj ) = @_; return ($obj->{value} < 0 ) ? 1 : 0; }
package Number; sub new { my ( $class, $value ) = @_ my $self = { parse_path => [], value => $value }; return bless $self, $class; }
use Decision::ParseTree q{ParseTree}; my $rules = Rules->new; my $tree = LoadFile('tree.yaml'); print ParseTree( $tree, $rules, Number->new(10) ); # Positive Number print ParseTree( $tree, $rules, Number->new(-1) ); # Negative Number print ParseTree( $tree, $rules, Number->new(0) ); # Looks like zero print ParseTree( $tree, $rules, Number->new('a')); # Non-Numeric Value
To make this all work we need a few parts:
A rules object: This will be a library of rules.
An object that will be passed thru the rules.
A YAML doc that outlines your decision tree.
So this all started as a way to make a decision tree thats easy to parse and easy to read for non-programmers. So to do this I looked to YAML, it's easy to read and easy to parse. Though make this work we have some hard and fast rules to follow for the tree construction:
RULES are a key value pair
the key is the method to run in the rules object
the value must be an arrayref or hashref
ARRAYS are a series of rules run in order
HASHES are a series of answers
SCALARS are endpoints
Sometimes you have to make things messy before they can get clean.
Theres a flexibility that comes with breaking things apart in to nice, neat little chunks. By separating the rule logic in to one place you can make very complex rules that do not gunk up your code. You pull the order of these rules in to another place as it's completely possible that you would want to tweak the order. And lastly you need to glue these separate things together, so you have an object that gets passed thru to make this all work. Tada!
It would be nice to whip up a big example here to show all the interesting bits, sadly I can't think of a good example. Ideas?
Selecting a tests to run for hardware
Building settings/configuration files on the fly for varried hardware.
Would any one like to use this to write up a GO AI engine? Chess?
tracking for free
If $obj->{parse_path} exists then every step that this obj takes thru the rules will be tracked. This path will be stored as an array ref, of hash refs.
$obj = Number->new(10); ParseTree( $tree, $rules, $obj ); # $obj->{parse_path} will now look like : # [ { 'is_num' => 1 }, # { 'is_pos' => 1 }, # ]
If $obj->{parse_answer} exists then, when an answer is found, then it gets stored here as well as being returned.
print $obj->{parse_answer}; # Positive Number
ParseTree is the only thing that can get exported, it's also the only thing in here, so export away.
Runs $obj thru $tree, using $rules as the library of rules.
Returns the first endpoint that you run into as the answer.
Currently $tree is expected to be a pre-parsed YAML File, This should change here soon to also accept a filename. Currently though it does not.
would like even more examples.
need to flush out the docs more.
ben hengst, <notbenh at cpan.org>
<notbenh at cpan.org>
Please report any bugs or feature requests to bug-decision-parsetree at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Decision-ParseTree. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
bug-decision-parsetree at rt.cpan.org
You can find documentation for this module with the perldoc command.
perldoc Decision::ParseTree
You can also look for information at:
AnnoCPAN: Annotated CPAN documentation
http://annocpan.org/dist/Decision-ParseTree
CPAN Ratings
http://cpanratings.perl.org/d/Decision-ParseTree
RT: CPAN's request tracker
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Decision-ParseTree
Search CPAN
http://search.cpan.org/dist/Decision-ParseTree
Copyright 2007 ben hengst, all rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
To install Decision::ParseTree, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Decision::ParseTree
CPAN shell
perl -MCPAN -e shell install Decision::ParseTree
For more information on module installation, please visit the detailed CPAN module installation guide.