Question re Conway's "Perl Best Practices" - Sort::Maker

Discussion in 'Perl Misc' started by usenet@DavidFilmer.com, May 4, 2006.

  1. Guest

    Uri reminded me (in another thread: http://tinyurl.com/nyclh) of his
    module, Sort::Maker, which Damian Conway praised in "Perl Best
    Practices" (page 164-165), and which I have been meaning to learn more
    about.

    However, I am having difficulty with Damian's example.

    Kindly consider this small sample program wrapped around some PBP
    example code which I have retyped verbatum (adding only my own
    statement to populate sample @names):

    #!/usr/bin/perl
    use strict; use warnings;
    use Sort::Maker;

    my @names = qw{ Fred Barney Wilma Betty };

    make_sorter(name => 'sort_len', code => sub{ length }, ST => 1);
    # and later...
    my @names_shortest_first = sort_len(@names);

    __END__

    The script fails with:
    Undefined subroutine &main::sort_len...

    But, according to the Sort::Maker perldocs, 'name' is
    >>> a value option which exports the generated sort sub to that name.


    So I believe that sort_len should be exported when the make_sorter
    statement is executed. But it doesn't seem to be working.

    What am I doing wrong?

    (perl, v5.8.4 built for aix, $Sort::Maker::VERSION == 0.05)


    --
    http://DavidFilmer.com
     
    , May 4, 2006
    #1
    1. Advertising

  2. DJ Stunks Guest

    wrote:
    > Uri reminded me (in another thread: http://tinyurl.com/nyclh) of his
    > module, Sort::Maker, which Damian Conway praised in "Perl Best
    > Practices" (page 164-165), and which I have been meaning to learn more
    > about.
    >
    > However, I am having difficulty with Damian's example.
    >
    > Kindly consider this small sample program wrapped around some PBP
    > example code which I have retyped verbatum (adding only my own
    > statement to populate sample @names):
    >
    > #!/usr/bin/perl
    > use strict; use warnings;
    > use Sort::Maker;
    >
    > my @names = qw{ Fred Barney Wilma Betty };
    >
    > make_sorter(name => 'sort_len', code => sub{ length }, ST => 1);
    > # and later...
    > my @names_shortest_first = sort_len(@names);
    >
    > __END__
    >
    > The script fails with:
    > Undefined subroutine &main::sort_len...
    >
    > But, according to the Sort::Maker perldocs, 'name' is
    > >>> a value option which exports the generated sort sub to that name.

    >
    > So I believe that sort_len should be exported when the make_sorter
    > statement is executed. But it doesn't seem to be working.
    >
    > What am I doing wrong?
    >
    > (perl, v5.8.4 built for aix, $Sort::Maker::VERSION == 0.05)


    Well, the first thing I did was grab my copy of _PBP_ and check that
    you weren't nuts. Which you aren't :)

    The second thing I did was run your sample code, with the same results.

    I then added an error check on the make_sorter call and it died with
    the error:
    Unable to create sorter: make_sorter: Unknown option or key 'code'

    So then I had a look at the docs (which I hadn't ever looked at before)
    and managed to munge up the following, which works.

    I'm sure Pastor Conway ran all the code in his book, so maybe something
    changed. Only Uri knows for sure.

    -jp

    #!/usr/bin/perl
    use strict; use warnings;

    use Sort::Maker;

    my @names = qw{ Fred Barney Wilma Betty };

    make_sorter(
    qw( ST ),
    name => 'sort_len',
    string => {
    code => sub { length }
    }
    ) or die "Unable to create sorter: $@";

    print join "\n", sort_len(@names);

    __END__
     
    DJ Stunks, May 4, 2006
    #2
    1. Advertising

  3. Uri Guttman Guest

    >>>>> "DS" == DJ Stunks <> writes:

    DS> So then I had a look at the docs (which I hadn't ever looked at before)
    DS> and managed to munge up the following, which works.

    DS> I'm sure Pastor Conway ran all the code in his book, so maybe something
    DS> changed. Only Uri knows for sure.

    DS> -jp

    DS> #!/usr/bin/perl
    DS> use strict; use warnings;

    DS> use Sort::Maker;

    DS> my @names = qw{ Fred Barney Wilma Betty };

    DS> make_sorter(
    DS> qw( ST ),
    DS> name => 'sort_len',
    DS> string => {
    DS> code => sub { length }
    DS> }
    DS> ) or die "Unable to create sorter: $@";

    DS> print join "\n", sort_len(@names);


    from the Changes file:

    0.04 Wed Apr 27 01:37:00 EDT 2005
    - fixed 'name' option bug, added test and docs
    -from Damian Conway <>

    so he found that bug and this was during the tech review period of PBP
    so i think the fix didn't get propogated back to the book. in any case
    you should always trust up to date docs in a module than any dead trees
    book that mentions a module and shows examples on how to use it.

    the best thing to do now is email damian and report this errata so he
    could put it in his errata page and possibly get it fixed in a future
    printing or edition.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, May 4, 2006
    #3
  4. Guest

    Uri Guttman wrote:
    > the best thing to do now is email Damian and report this errata


    Thanks for your reply, Uri. I have submitted an errata report on the
    O'Reilly website, as they provide an easy mechanism to facilitate this.

    --
    http://DavidFilmer.com
     
    , May 4, 2006
    #4
  5. >>>>> "Uri" == Uri Guttman <> writes:

    Uri> the best thing to do now is email damian and report this errata so he
    Uri> could put it in his errata page and possibly get it fixed in a future
    Uri> printing or edition.

    Please don't "email the author" for an O'Reilly book to report errata.
    O'Reilly's web page for a given book has a clearly marked "report and see
    errata for this book" link. Use that instead.

    Part of the services of a major publisher is to track and update errata, so
    that the author does not need to do that directly. I'm surprised Uri was
    unaware of that.

    --
    Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
    <> <URL:http://www.stonehenge.com/merlyn/>
    Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
    See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

    *** Posted via a free Usenet account from http://www.teranews.com ***
     
    Randal L. Schwartz, May 4, 2006
    #5
  6. wrote:
    > Uri reminded me (in another thread: http://tinyurl.com/nyclh) of his
    > module, Sort::Maker, which Damian Conway praised in "Perl Best
    > Practices" (page 164-165), and which I have been meaning to learn more
    > about.
    >
    > However, I am having difficulty with Damian's example.
    >
    > Kindly consider this small sample program wrapped around some PBP
    > example code which I have retyped verbatum (adding only my own
    > statement to populate sample @names):
    >
    > #!/usr/bin/perl
    > use strict; use warnings;
    > use Sort::Maker;
    >
    > my @names = qw{ Fred Barney Wilma Betty };
    >
    > make_sorter(name => 'sort_len', code => sub{ length }, ST => 1);
    > # and later...
    > my @names_shortest_first = sort_len(@names);
    >
    > __END__


    you would probably want to have a look at Sort::Key module also. It is
    usually faster than Sort::Maker and IMO easier to use.

    For instance to sort by length:

    use Sort::Key qw(ikeysort);

    my @names = qw{ Fred Barney Wilma Betty };
    my @names_shortest_first = ikeysort { length } @names;

    or alternatively:

    use Sort::Key::Maker sort_len => sub { length }, qw(integer);

    my @names = qw{ Fred Barney Wilma Betty };
    my @names_shortest_first = sort_len @names;

    Cheers,

    - Salva
     
    Salvador Fandino, May 4, 2006
    #6
  7. Uri Guttman Guest

    >>>>> "SF" == Salvador Fandino <> writes:

    SF> you would probably want to have a look at Sort::Key module also. It is
    SF> usually faster than Sort::Maker and IMO easier to use.

    i find the massive number of different exported functions, including
    ones created on the fly to be more confusing. but timtowtdi rules apply.

    as for faster, your module appears to do its key extractions and
    compares in each compare block which are O(N log N). the GRT and ST
    (both of which can be used in sort::maker) factor out the extractions
    and makes them O(N) and that can be a major savings in large complex
    sorts. so stating a module is usually faster than another should be
    qualified with what criteria are used to compare them.

    SF> For instance to sort by length:

    SF> use Sort::Key qw(ikeysort);

    SF> my @names = qw{ Fred Barney Wilma Betty };
    SF> my @names_shortest_first = ikeysort { length } @names;

    as i said above the multiple exported subs is not a style i like. also a
    single exported sub with a well defined arg list can be more easily used
    to autogenerated sort subs from a record description.

    finally, sort::maker comes with a table driven test and benchmark
    system. it should be easy for you to run it on your module and then we
    can benchmark a wide range of datasets and sorts and see how the
    different modules behave. i am very interested in seeing some apples to
    apples results.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, May 4, 2006
    #7
  8. Uri Guttman wrote:
    >>>>>>"SF" == Salvador Fandino <> writes:

    >
    >
    > SF> you would probably want to have a look at Sort::Key module also. It is
    > SF> usually faster than Sort::Maker and IMO easier to use.
    >
    > i find the massive number of different exported functions, including
    > ones created on the fly to be more confusing. but timtowtdi rules apply.
    >
    > as for faster, your module appears to do its key extractions and
    > compares in each compare block which are O(N log N).


    No, keys are precomputed before sorting

    > the GRT and ST
    > (both of which can be used in sort::maker) factor out the extractions
    > and makes them O(N) and that can be a major savings in large complex
    > sorts. so stating a module is usually faster than another should be
    > qualified with what criteria are used to compare them.


    Sort::Key is faster than the ST or GRT sorting arrays of any lenght in
    most cases. Only for some rare cases of key type combinations and data
    could be the GRT a bit faster, but most of the times is the other way

    > SF> For instance to sort by length:
    >
    > SF> use Sort::Key qw(ikeysort);
    >
    > SF> my @names = qw{ Fred Barney Wilma Betty };
    > SF> my @names_shortest_first = ikeysort { length } @names;
    >
    > as i said above the multiple exported subs is not a style i like. also a
    > single exported sub with a well defined arg list can be more easily used
    > to autogenerated sort subs from a record description.


    that functionality is also available from the Sort::Key::Maker module.
    You can create new sorters on the fly just defining the types of the keys:

    use Sort::Key::Maker my_sort => qw(number -number string);

    my @sorted = my_sort { $_->{foo}, $_->{bar}, $_->{doz} } @data;


    or alternatively you can attach the keys extraction sub to the sorter:

    use Sort::Key::Maker my_sort =>
    sub { $_->{foo}, $_->{bar}, $_->{doz} }
    qw(number -number string);

    my @sorted = my_sort @data;



    > finally, sort::maker comes with a table driven test and benchmark
    > system. it should be easy for you to run it on your module and then we
    > can benchmark a wide range of datasets and sorts and see how the
    > different modules behave. i am very interested in seeing some apples to
    > apples results.


    well, I already have some benchmark scripts of my own as for instance
    the one attached:

    $ for i in str num int num_str str_num; do perl ben2.pl -t $i; done

    comparing sorters for str keys with 500000 elements:
    s/iter sm skm sk
    sm 6.58 -- -26% -28%
    skm 4.85 36% -- -2%
    sk 4.73 39% 3% --

    comparing sorters for num keys with 500000 elements:
    s/iter sm skm sk
    sm 6.71 -- -71% -73%
    skm 1.94 246% -- -5%
    sk 1.84 265% 5% --

    comparing sorters for int keys with 500000 elements:
    s/iter sm skm sk
    sm 5.94 -- -69% -70%
    skm 1.85 221% -- -5%
    sk 1.76 238% 5% --

    comparing sorters for num_str keys with 500000 elements:
    s/iter sm skm
    sm 8.13 -- -31%
    skm 5.62 45% --

    comparing sorters for str_num keys with 500000 elements:
    s/iter sm skm
    sm 7.97 -- -35%
    skm 5.17 54% --

    (sm => Sort::Maker, sk => Sort::Key, skm => Sort::Key::Maker)

    Cheers,

    - Salvador
     
    Salvador Fandino, May 5, 2006
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Putty

    Conway's Life Implementation

    Putty, Aug 27, 2006, in forum: Python
    Replies:
    4
    Views:
    417
    Andrew Trevorrow
    Aug 28, 2006
  2. Uri Guttman

    boston perl classes with damian conway

    Uri Guttman, Sep 16, 2003, in forum: Perl Misc
    Replies:
    15
    Views:
    177
    Graham Drabble
    Oct 2, 2003
  3. Sunil Choudhary

    SourceCode : perl OOPS by Conway:

    Sunil Choudhary, Jan 11, 2004, in forum: Perl Misc
    Replies:
    5
    Views:
    116
    Matt Garrish
    Feb 7, 2004
  4. Replies:
    9
    Views:
    184
    Anno Siegel
    Jan 19, 2006
  5. Uri Guttman

    Free Perl Training with Damian Conway

    Uri Guttman, Mar 25, 2008, in forum: Perl Misc
    Replies:
    1
    Views:
    93
    David Combs
    Apr 21, 2008
Loading...

Share This Page