|
Posted by Mumia W. (reading news) on December 5, 2006, 2:55 pm
Please log in for more thread options
On 12/05/2006 10:49 AM, harryfmudd [AT] comcast [DOT] net wrote:
> Mumia W. (reading news) wrote:
>> I wanted to see how Sort::Maker could be used to sort the "meascodes"
>> in this message:
>>
>>
http://groups.google.com/groups?selm=1165272390.675288.234670@79g2000cws.googlegroups.com
>> [...]
>>
>> Evidently, there is a bug/undocumented feature that causes an
>> anonymous sub that the programmer writes in his package to be compiled
>> in Sort::Maker, and Sort::Maker seems to make some modifications to
>> the *text* of that subroutine before it's compiled :O
>> [...]
>
> Well, it's quasi-documented. The third paragraph in "Key Extraction
> Code" about 60% of the way down the POD says "If a CODE reference is
> used, then the B::Deparse module is used to deparse it back into Perl
> source. [...]
Gotcha. With that information, I decided to try a string rather than a
CODE reference:
use strict;
use warnings;
use Data::Dumper;
use Sort::Maker;
no warnings 'once';
our $cost_order = 'A2yB';
my @sorted;
my $ms = [
'<table><tr><td meascode=\'y\'> </td></tr></table>',
'<table><tr><td meascode=\'B\'> </td></tr></table>',
'<table><tr><td meascode=\'2\'> </td></tr></table>',
'<table><tr><td meascode=\'A\'> </td></tr></table>'
];
my $sorter = make_sorter(
plain => string => q{
if (/meascode='(.)'/)
},
);
if ($@) { print "$@\n"; exit; }
@sorted = $sorter->(@$ms);
print Dumper(\@sorted);
__END__
And it works.
TIMTOWAROUND
--
paduille.4060.mumia.w@earthlink.net
|
|
Posted by Uri Guttman on December 5, 2006, 3:17 pm
Please log in for more thread options
writes:
MW(n> Gotcha. With that information, I decided to try a string rather than a
MW(n> CODE reference:
MW(n> our $cost_order = 'A2yB';
MW(n> my @sorted;
MW(n> my $sorter = make_sorter(
MW(n> plain => string => q{
MW(n> if (/meascode='(.)'/)
MW(n> },
that is using a global which can be dangerous. see my other post for a
proper solution. also it shows a cleaner bit of key extraction
code. that code uses the last expression of an if block for its value
which is naughty IMO. and if the regex fails what do you do? hell, my
example doesn't even check that too. but it does make that code into a
proper expression with && and not the if block (which is also slower).
MW(n> And it works.
good!
MW(n> TIMTOWAROUND
and some are better than others! :)
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
|
|
Posted by Uri Guttman on December 5, 2006, 2:38 pm
Please log in for more thread options
writes:
MW(n> 137 my $cost_order = 'A2yB';
MW(n> 138 my @sorted;
MW(n> 139
MW(n> 140 my $ms = [
MW(n> 141 '<table><tr><td meascode=\'y\'> </td></tr></table>',
MW(n> 142 '<table><tr><td meascode=\'B\'> </td></tr></table>',
MW(n> 143 '<table><tr><td meascode=\'2\'> </td></tr></table>',
MW(n> 144 '<table><tr><td meascode=\'A\'> </td></tr></table>'
MW(n> 145 ];
MW(n> 146
MW(n> 147 my $sorter = make_sorter(
MW(n> 148 plain => string => sub {
MW(n> 149 if (/meascode='(.)'/)
MW(n> 150 },
MW(n> 151 );
MW(n> 152 if ($@) { print "$@\n"; exit; }
MW(n> 153 @sorted = $sorter->(@$ms);
MW(n> 154 print Dumper(\@sorted);
MW(n> I was a little surprised, since anonymous subs usually have access to
MW(n> lexical variables. I decided to make $cost_order a package variable
MW(n> (in main) and fully qualify it as $::cost_order in the anonymous sub,
MW(n> so I changed the lines of the program like so:
sort::maker builds a sort sub source and evals it. so that is done in
the Sort::Maker namespace as you learned later on. there is no way for
that code to see any lexicals or subs outside its space.
MW(n> 137 sub COST_ORDER { 'A2yB' }
MW(n> 146 * = \&COST_ORDER;
MW(n> 149 if (/meascode='(.)'/)
MW(n> And it works.
MW(n> Evidently, there is a bug/undocumented feature that causes an
MW(n> anonymous sub that the programmer writes in his package to be compiled
MW(n> in Sort::Maker, and Sort::Maker seems to make some modifications to
MW(n> the *text* of that subroutine before it's compiled :O
there is a feature you missed which can help here. the 'init_code'
option allows you to put arbitrary code into the sort sub. this is
useful when you do work in one key extraction and generate multiple
keys. you can declare a temp var in init_code and assign it in one
extraction for use by later keys. in this case it can be used to set the
sort order string. this is a tested example. it prints out the sorter so
you see how the init_code is used.
#!/usr/local/bin/perl
use strict ;
use warnings ;
use Sort::Maker qw( make_sorter sorter_source ) ;
my @unsorted = (
'<table><tr><td meascode="y"></td></tr></table>',
'<table><tr><td meascode="2"></td></tr></table>',
'<table><tr><td meascode="A"></td></tr></table>',
'<table><tr><td meascode="B"></td></tr></table>',
) ;
my $sorter = make_sorter(
'GRT',
init_code => 'my $cost_order = q;',
signed => 1,
string_data => 1,
number => q{ /code="(.)"/ && index($cost_order,$1) },
) ;
$sorter or die $@ ;
print sorter_source( $sorter ) ;
print map "$_\n", $sorter->( @unsorted ) ;
if you want the $cost_order to come from the outside, you can just use a
variable in the init_code and change it to "".
my $cost_order = 'A2yB';
my $sorter = make_sorter(
'GRT',
init_code => "my $cost_order = '$cost_order' ;",
signed => 1,
string_data => 1,
number => q{ /code="(.)"/ && index($cost_order,$1) },
) ;
both output this:
<table><tr><td meascode="A"></td></tr></table>
<table><tr><td meascode="2"></td></tr></table>
<table><tr><td meascode="y"></td></tr></table>
<table><tr><td meascode="B"></td></tr></table>
and that appears to be the desired order.
note that i do a numeric compare on the index() value as a string compare
would fail when you get to more than 1 digit.
also see how i simplified getting the index value in the key extraction.
expressiveness like this is one of the major wins of Sort::Maker over
rolling your own sorts besides the speedup if you use the GRT.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
|
|
Posted by Mumia W. (reading news) on December 5, 2006, 4:12 pm
Please log in for more thread options
On 12/05/2006 01:38 PM, Uri Guttman wrote:
> [...]
> my $cost_order = 'A2yB';
>
> my $sorter = make_sorter(
> 'GRT',
> init_code => "my $cost_order = '$cost_order' ;",
> signed => 1,
> string_data => 1,
> number => q{ /code="(.)"/ && index($cost_order,$1) },
> ) ;
> [...]
It's a little more interesting if a CODE reference is used since only a
CODE ref is deparsed:
number => sub { /code="(.)"/ && index($cost_order,$1) },
But it does work the same way.
--
paduille.4060.mumia.w@earthlink.net
|
|
Posted by Uri Guttman on December 5, 2006, 5:31 pm
Please log in for more thread options
writes:
MW(n> On 12/05/2006 01:38 PM, Uri Guttman wrote:
>> [...]
>> my $cost_order = 'A2yB';
>> my $sorter = make_sorter(
>> 'GRT',
>> init_code => "my $cost_order = '$cost_order' ;",
>> signed => 1,
>> string_data => 1,
>> number => q{ /code="(.)"/ && index($cost_order,$1) },
>> ) ;
>> [...]
MW(n> It's a little more interesting if a CODE reference is used since only
MW(n> a CODE ref is deparsed:
MW(n> number => sub { /code="(.)"/ && index($cost_order,$1) },
MW(n> But it does work the same way.
did you try that? when i do i get that $cost_order is not declared in
the internal eval. the dumped source code shows that. the reason i
didn't wan't to support just calling the code refs was for speed. the
code ref would need to be called for each sort element and that is a
sizeable extra overhead compared to running the code inline as it does
now. maybe an option can be added to call the coderef instead of
deparsing it so you can use closures for key extractions. shouldn't be
too hard to do. it would be 1 option to parse, pod for it, and a small
conditional and code generation change. wanna tackle it? :)
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
|
| Similar Threads | Posted | | ANNOUNCE: Sort::Maker .02 | September 2, 2004, 5:09 am |
| Accomodate for poor db design using Sort::Maker? | December 9, 2006, 12:48 am |
| Sort::Maker: style => 'plain' difficulty | December 14, 2006, 4:35 am |
| Sort::Maker: (Notes) The plain and the orcish don't include the "init_code" | December 14, 2006, 7:32 am |
| Pre-compiled SSL Perl modules | August 6, 2006, 7:11 am |
| Using Set::Object - evidently I need compiled code? | March 31, 2008, 10:21 pm |
| [ANN] Sort::Key 0.02 | April 28, 2005, 11:02 am |
| Compiled .exe of Perl does not work when using Crypt::SSLeay | May 14, 2007, 7:35 pm |
| Running compiled Inline C perl scripts on more than one machine | February 9, 2006, 12:12 pm |
| unusual behaviour of perl script compiled with perlapp on hp-ux11i | May 8, 2005, 7:52 am |
|