Pass code reference to sort function

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View

I'm trying to build a very minimal ETL tool using Perl.  I'm trying as
much as possible to abstract the gory details of reading, writing and
generally processing the data by providing a pre-built pipeline into
which users can plug various bits of functionality.

One of the pieces that I'd like to plug in is the ability to sort data
retrieved from a data source.  What I'd like to do is to have the user
specify the block to be used by the sort function, something like the

$csv = ETL::Reader::CSV('/my/file/name') ;
$sort_block = sub { $a-> cmp $b } ;
$csv->set_order($sort_block) ;

The set_order method is simply an attribute setter method in the
ETL::Reader::CSV class, ie it sets $self-> to the passed value.

Within the CSV data source class, I'd like to be able to sort the data
by passing the code reference to the sort function.  I've (naively)
tried the following:

@sorted = sort }} @unsorted

This appears to be syntactically correct, but it doesn't sort the data,
or indeed even execute the function.

Anybody have any ideas ?  Is this something to do with the lexical
definition of the $a and $b variables ?  Is there any way to do what I'd
like to do ?

Re: Pass code reference to sort function

Quoted text here. Click to load it

    my $sortsub = $self->;
    @sorted = sort $sortsub @unsorted;

I don't think the syntax will let you have anything other than a simple
scalar there, so you have to use a temporary.

Quoted text here. Click to load it

You also need to make sure your sort call is in the same package as the
sub was compiled in, or it won't be able to find $a and $b. If you
really need to use subs compiled in arbitrary packages, you can use
something like

    use Sub::Identify qw/stash_name/;

    my $pkg = stash_name $sortsub;
        no strict "refs";
        local (*a, *b) = (\*, \*);
        @sorted = sort $sortsub @unsorted;

or you can use an ($$)-prototyped sort sub, in which case the arguments
come in in @_ instead (this is slower, though).


Re: Pass code reference to sort function

Ben Morrow wrote:

Quoted text here. Click to load it
Thanks very much, the prototyped sub with the temporary worked great,
the second solution looks really clever, but looks like something that
might be nigh on unmaintainable in a couple of months time so discretion
might be the best part of valor for me there.

Thanks for you help !

Site Timeline