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]

Reply via email to