davidnicol has asked for the wisdom of the Perl Monks concerning the following question:

I am writing a module that ideally will use sort-style comparison functions that take the two sides using the "special" $a and $b variables. But a simple test

perl -le ' $a=27; package foo; print $a'

indicates that $a is not as special as, say, $_{a} would be.

So here's the question:

how do I load data into $a and $b so that a sort comparator defined in a distant module can see them?

I can fall back to having the comparator function take $_[0] and $_[1] if I must.

Replies are listed 'Best First'.
Re: just how special are $a and $b these days?
by ikegami (Patriarch) on Mar 03, 2010 at 22:51 UTC
    sub func_using_comparer(&@) { my $cb = shift; my $ap = do { no strict 'refs'; \*{caller().'::a'} }; my $bp = do { no strict 'refs'; \*{caller().'::b'} }; local *$ap; local *$bp; ... loop { ... *$ap = \$value1; *$bp = \$value2; $cb->(); ... }; ... }
Re: just how special are $a and $b these days?
by AnomalousMonk (Archbishop) on Mar 03, 2010 at 22:53 UTC

    About as special as they always have been.

    They continue to be package variables. As such, they must be accessed from other packages by their fully qualified names. I'm sure there are familiar methods to import package variables from one package to another, but I don't recall them at the moment. Perhaps others...?

    >perl -wMstrict -le "$a=27; package foo; print $::a; " 27
Re: just how special are $a and $b these days?
by sauoq (Abbot) on Mar 03, 2010 at 22:55 UTC
    how do I load data into $a and $b so that a sort comparator defined in a distant module can see them?

    I'm not sure exactly what you are trying to do. Can you explain it in pseudocode? There is no problem with having a comparator function defined in a "distant module". The $a and $b variables are package variables. If you absolutely had to set them from some other module (which seems unlikely or at least unlikely to be a good practice) you could specifically reference the package that the sort comparator function is defined in.

    -sauoq
    "My two cents aren't worth a dime.";

      What I'm trying to do is write a binary search module that takes the same comparator function that was used to sort the array being search.

      I'm getting the idea here that since $a and $b are package variables, sort comparators need to be declared in the same package as their use. I had thought that, for instance

      # the following is dumb and is written strictly as an example package backwards; sub pmc { $b cmp $a }; package main; print sort backwards::pmc ( split /\s+/, `cat $0` )

      would work as intended.

      it doesn't

      so it looks like ${caller().'::a'} is going to be where the search key goes, and ${caller().'::b'} is going to be where the guesses go for evaluation. Done with glob aliasing, of course.

      Thank you everyone

        This does:

        package backwards; sub pmc { $::b cmp $::a }; package main; print sort backwards::pmc ( split /\s+/, `cat $0` )
        c:\test>junk66 };{subsplitsortprintpmcpackagepackagemain;cmpbackwards;backwards::pmc` +cat/\s+/,)($::b$::a$0`

        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: just how special are $a and $b these days?
by BrowserUk (Patriarch) on Mar 04, 2010 at 00:00 UTC
    c:\test>perl -l package distant; sub comp{ $::a <=> $::b || $::b cmp $::a }; package main; print for sort distant::comp qw[ 3 3.0 3e0 2 2.0 2e0 1 1.0 1e0 ] ^Z 1e0 1.0 1 2e0 2.0 2 3e0 3.0 3

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: just how special are $a and $b these days?
by DrHyde (Prior) on Mar 04, 2010 at 10:52 UTC

    perldoc -f sort has a vast amount of information on writing sort subroutines.

    But if all you want to do is use a function from some random module to do the comparison, how about ...

    @output = sort { Some::Module::comparison($a, $b) }  @input

      Or, if you really want to, you can overload cmp as a call to Some::Module::comparison, and then as long as $a and $b are objects of that module, they'll sort automatically.

Re: just how special are $a and $b these days?
by sauoq (Abbot) on Mar 04, 2010 at 22:26 UTC

    I understand the question now.

    The prescribed way to do this is to prototype your comparator function with ($$) and to use @_.

    -sauoq
    "My two cents aren't worth a dime.";