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

So I've got this custom sort function like so:
our %df_keys; sub directories_first { return ($df_keys{$main::a}||=df_key($main::a)) cmp ($df_keys{$main +::b} ||= df_key($main::b)); }
It lives in a package, but it's automatically exported. Now, since $a and $b live in main::, I have to explicitly look them up in that package.

Or do I? Is there another way to say "Hey, $a and $b are in main::"?

xoxo,
Andy
--
<megaphone> Throw down the gun and tiara and come out of the float! </megaphone>

Replies are listed 'Best First'.
(Ovid) Re: Specifying main:: scope
by Ovid (Cardinal) on Dec 05, 2001 at 03:23 UTC

    I am not sure exactly what you're asking. You wrote that $a and $b live in %main::, but in a sort routine, they actually are package globals in whatever package you currently happen to be in. Now, if you're stating that the variables that $a and $b are comparing live in %main:, that's irrelevant because they are aliasing the original variables.

    If you want to use &directories_first as a sort routine, but it might be in a different package, you can use prototypes:

    our %df_keys; sub directories_first ($$) { $df_keys{$_[0]} ||= df_key($_[0]); $df_keys{$_[1]} ||= df_key($_[1]); return ( $df_keys{$_[0]} cmp $df_keys{$_[1]} ); } # somewhere else in the galaxy: my @new_array = sort Some::Package::directories_first @old_array;

    See perldoc -f sort for details. I hope this helps because I really didn't understand your question :)

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: Specifying main:: scope
by wog (Curate) on Dec 05, 2001 at 03:16 UTC
    To say that $a and $b are in main:: you can use something like:

    package main; our($a,$b); package RealPackage; # ...

    However, I think you are doing something that is not a good idea. Since you seem to have perl >=5.6, I would reccommend using a function with a prototype of ($$) as your sort routine:

    sub directories_first ($$) { my ($a,$b) = @_; # ... }

    Otherwise, if your function is to work should you want to use it in a package besides main you're going to need to do something to use the correct package's variable, such as dynamically generating the function on export or using symbolic references.

Re: Specifying main:: scope
by runrig (Abbot) on Dec 05, 2001 at 03:47 UTC
      I notice that japhy says to use local and Ovid says to use my ... anyone have a preference and reason?

      ------
      We are the carpenters and bricklayers of the Information Age.

      Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

        Ovid is just using @_ directly. If the arguments are passed to the sub via local or my variables, it doesn't matter what they're called. The important thing is to use prototypes for the sort function. With that in mind, I think I'd still avoid local, and either use @_ directly or lexical/my variables.
Re: Specifying main:: scope
by chip (Curate) on Dec 05, 2001 at 06:04 UTC
    Also, $::a is a shorter way to type $main::a.

        -- Chip Salzenberg, Free-Floating Agent of Chaos

      And (just for fun) $main::main::main::a is a longer way to type </code>$main::a</code>

      i.e. 'main' is somewhat like a symbolic link back to itself.....

      -Blake