http://www.perlmonks.org?node_id=129010

I was playing with Filter::Simple and reading up on Programming by Example http://lieber.www.media.mit.edu/people/lieber/PBE/ and came up with this toy module. I have a feeling that this could be much better implemented, and actually become useful. Welcome comments, improvements, criticism!

package Example; use Filter::Simple; use Text::ParseWords; use Text::Balanced qw(extract_codeblock); FILTER { my $text=$_; my $output=''; # find a subroutine while ($text=~m[\A(.*?\bsub\s+.*?)(\{.*)$]sg) { $output.=$1; $code=$2; # extract a codeblock to examine. my ($ex, $re)=extract_codeblock($code, '{}'); # does it include the example(...,...) statement if ($ex=~s{\bexample\s*\((.*)\);?\s*$}{my \@args=\@_;}m) { # find the example arguments, and create a hash # to generalise them using a regex: my @args=quotewords(',',0,$1); my $arg_num=0; my %args=map {$_,"\$args[".$arg_num++."]"} @args; my $arg_re=join '|', map { "$_" } sort {length($b) <=> length($a) }@args; # above so that if there are 2 arguments # one of which includes the other, the # longest will be applied first! # Apply the regex to everthing within the codeblock. $ex=~s{($arg_re)} {$args{$1}}g; } $output.="$ex"; $text=$re; } $_=$output.$text; #print ; # uncomment this line to see the filtered source }; 1 ; =head1 NAME Example.pm =head1 DESCRIPTION A very very badly written demonstration of =over 4 =item 1 The L<Filter::Simple> module. (Very cool) =item 2 Programming by example. See http://lieber.www.media.mit.edu/people/li +eber/PBE/ for more details. Essentially, the idea is that the computer should w +atch what is being done, and attempt to extrapolate this into the actual co +de. I suspect that the approach I've taken here isn't really the most shin +ing example of this... More in the books "Watch what I do" and "Your Wish is my command", links from the above site. Also look out for Toon Talk ( http://www.t +oontalk.com/ )- most easily described as a cross between a programmin +g language and a computer game. =back =head1 USAGE Note that L<Filter::Simple> and L<Text::Balanced> (both by TheDamian) +must be installed. use Example In every subroutine that you want to write by example, include a line +at the beginning example(1,2,3); with the arguments that you pass in. When the program is run every re +ference to those arguments will be changed into the relevant argument. Perhap +s this is best demonstrated by... =head1 EXAMPLE use Example; sub add { example(1,11); print "1+11="; print 1+11; } sub concat { example("Hello","World"); print "Hello World"; } add (4, 5); print "\n"; concat("Bonjour", "Monde"); =head1 ...WHICH BECOMES... sub add { my @args=@_; print "$args[0]+$args[1]="; print $args[0]+$args[1]; } sub concat { my @args=@_; print "$args[0] $args[1]"; } add (4, 5); print "\n"; concat("Bonjour", "Monde"); =head1 BUGS - Parsing of the comma separated list of example inputs C<example> is buggy for anything other than simple inputs. - Though the longest arguments are generalised first, there is no cont +ext sensitivity. The example values passed to C<example(..., ...)> should + be written so as not to conflict with anything else in the subroutine... - With the example above, you couldn't write C<print "1+11=12"> and ha +ve L<Example.pm> I<do the right thing>... =head1 VERSION and AUTHOR v 0.0000001 status: unstable, untested hakim@earthling.net http://www.perlmonks.org -> /msg osfameron =cut

Cheerio!
Osfameron