*** Maker.src Wed Dec 6 06:27:46 2006 --- Maker.pm Mon Dec 18 02:35:53 2006 *************** *** 8,14 **** %EXPORT_TAGS = ( 'all' => [ qw( sorter_source ), @EXPORT ] ); @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); ! $VERSION = '0.05'; use strict; --- 8,14 ---- %EXPORT_TAGS = ( 'all' => [ qw( sorter_source ), @EXPORT ] ); @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); ! $VERSION = '0.07'; use strict; *************** *** 29,34 **** --- 29,35 ---- signed_float unsigned_float varying + closure ) ; my @value_attrs = qw( *************** *** 119,124 **** --- 120,129 ---- my $sorter ; + # Make the closures available to the eval-ed sub. + my $closures; + $closures = $options->{parser_opts}{closures} if ($options->{closure}); + { local( $SIG{__WARN__} ) = sub { $eval_warnings .= $_[0] } ; $sorter = eval $source ; *************** *** 152,157 **** --- 157,167 ---- my( %options, @keys ) ; + $options{parser_opts} = { + closures => [], + 'package' => (caller 1)[0], + }; + while( @_ ) { my $opt = shift ; *************** *** 274,280 **** # get the extraction code and return if any errors ! $key->{'code'} = get_extractor_code( $key->{'code'} ) ; return unless $key->{'code'} ; # set descending if it is not ascending and the default is descending. --- 284,290 ---- # get the extraction code and return if any errors ! $key->{'code'} = get_extractor_code( $key->{'code'}, $opts ) ; return unless $key->{'code'} ; # set descending if it is not ascending and the default is descending. *************** *** 307,313 **** sub get_extractor_code { ! my ( $extract_code ) = @_; # default extract code is $_ --- 317,324 ---- sub get_extractor_code { ! my ( $extract_code, $opts ) = @_; ! my $parser_opts = $opts->{parser_opts}; # default extract code is $_ *************** *** 331,336 **** --- 342,357 ---- return ; } + # If the "closure" option is specified, save the + # closure onto an array and return code that will + # (eventually) invoke it. + + if ($opts->{closure}) { + my $clo = $parser_opts->{closures}; + push @$clo, $extract_code; + return "\$closures->[$#{$clo}]->()"; + } + # Otherwise, try to decompile with B::Deparse... unless( require B::Deparse ) { *************** *** 1006,1012 **** And the make_sorter call is: my $sorter = make_sorter( ! style => 'ST', init_code => 'my( $str, $num ) ;', string => 'do{( $str, $num ) = $_->[0][0]{a} =~ /^(\w+):(\d+)$/; $str}', --- 1027,1033 ---- And the make_sorter call is: my $sorter = make_sorter( ! 'ST', init_code => 'my( $str, $num ) ;', string => 'do{( $str, $num ) = $_->[0][0]{a} =~ /^(\w+):(\d+)$/; $str}', *************** *** 1029,1034 **** --- 1050,1064 ---- perl t/init_code.t -bench + =head3 C + + This tells Sort::Maker to not deparse the CODE reference you give + it but instead to use it directly. This probably disables some + opportunities for optimization of the key extraction code, but it's + necessary for situtations where your key extraction code must access + lexical variables. + + =head2 Key Description Arguments Sorting data requires that records be compared in some way so they can