Robert Freimuth wrote:
> Hello everyone,
>
> I was reading about sort in the camel (3rd ed., p. 793) and I found that
> sorting subroutines must be placed in the same package as they are called
> from since $a and $b are package globals. Therefore, sorting functions
> cannot be "modulized" without help. The camel suggests two workarounds:
> qualifying $a and $b with the package name of the caller, and passing $a and
> $b as arguments (which also requires prototyping the sorting function and
> declaring $a and $b as lexicals).
>
> I was able to get the second method to work, but not the first. Could
> someone please explain (and provide an example of) how the package name of
> the calling function can be used to qualify $a and $b, as suggested in the
> camel? I tried playing around with the *{foo}{PACKAGE} and *{foo}{NAME}
> notation, but without success.
>
> On a related note, is one of these two methods preferred over the other?
>
> Here are the tests I've tried. Both give the expected output:
>
> unsorted: 1 9 5 10 2
> sorted: 1 2 5 9 10
>
> ** sort routine in same package **
> SORTTEST.PL:
>
> use strict;
> use warnings;
>
> my @nums = qw( 1 9 5 10 2 );
>
> print "unsorted: @nums\n";
> @nums = sort numerically @nums;
> print "sorted: @nums\n";
>
> sub numerically
> {
> $a <=> $b;
> }
>
> ** sort routine in a separate package **
> SORTTEST.PL:
>
> use strict;
> use warnings;
> use Sort_Numerically;
>
> my @nums = qw( 1 9 5 10 2 );
>
> print "unsorted: @nums\n";
> @nums = sort numerically @nums;
> print "sorted: @nums\n";
>
>
> SORT_NUMERICALLY.PM:
>
> package Sort_Numerically;
> use strict;
> use warnings;
> use Exporter;
> our @ISA = ( "Exporter" );
> our @EXPORT = ( "numerically" );
>
> sub numerically ($$)
> {
> my ( $a, $b ) = @_;
> $a <=> $b;
> }
Hi Bob.
The fully-qualified name of a package scalar variable is $package::name,
so in your program you want $main::a and $main::b. See my variation below,
together with a generalised sort subroutine which gets the name of the
calling code's package using the builtin 'caller' funciton. Note also that
there's no need to pull the parameters out of the @_ variable: you can use
it directly as $_[0] and $_[1] for $a and $b respectively.
HTH,
Rob
use strict;
use warnings;
use Sort_Numerically;
my @nums = qw( 1 9 5 10 2 );
my @sort;
print "unsorted: @nums\n";
@sort = sort numerically @nums;
print "sorted: @sort\n";
@sort = sort numerically1 @nums;
print "sorted: @sort\n";
@sort = sort numerically2 @nums;
print "sorted: @sort\n";
>> Sort_Numerically.pm
package Sort_Numerically;
use strict;
use warnings;
use Exporter;
our @ISA = ( "Exporter" );
our @EXPORT = qw /numerically numerically1 numerically2/;
sub numerically ($$)
{
$_[0] <=> $_[1];
}
sub numerically1 {
$main::a <=> $main::b;
}
sub numerically2 {
my $pkg = caller;
no strict 'refs';
${"${pkg}::a"} <=> ${"${pkg}::b"};
}
>> OUTPUT
unsorted: 1 9 5 10 2
sorted: 1 2 5 9 10
sorted: 1 2 5 9 10
sorted: 1 2 5 9 10
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]