in reply to Need an $a and $b as in perl's sort routine

Use dynamic variables. And then localize them in the sub doing the calling. Using variables names that start with :: will force them into main.

sub exec_callback { my $code=shift; local $::hash={}; local $::row=1; $code->(); }

This is basically all that happens with $_ or $a and $b in a sort routine or map or File::Find or Scalar::List::Utils. $a and $b are declared "special" so there shouldnt be any conflicts with them. Using $main::hash ($::hash) might have the potential for conflict.

---
$world=~s/war/peace/g

Replies are listed 'Best First'.
Re^2: Need an $a and $b as in perl's sort routine
by rational_icthus (Sexton) on Jan 10, 2006 at 23:57 UTC
    Wouldn't doing a local $::row={} leave '$row' defined in main even outside the code block, however? I'd like $row to disappear once the instruction is complete.

      No it wouldn't. Or rather $::row would revert to whatever it was before you localized it once you exited the sub that contains the localization. In the example below i use a bare block instead of sub to demonstrate but the same thing applies.

      D:\dev\PM>perl -le"$::x='outer'; $c=sub{print $::x}; { local $::x='inn +er'; $c->() } $c->()" inner outer

      Thats the whole point of dynamic scoping...

      ---
      $world=~s/war/peace/g

Re^2: Need an $a and $b as in perl's sort routine
by duelafn (Parson) on Jan 11, 2006 at 14:54 UTC

    But then the code is not usable from a module, no?

    I have used things like the following in the past:

    sub exec_callback { my $code = shift; my $caller = caller; no strict 'refs'; no warnings 'once'; local(*{$caller."::a"}) = \my $a; local(*{$caller."::b"}) = \my $b; $a = {}; $b = 1; $code->(); }

    Good Day,
        Dean

      But then the code is not usable from a module, no?

      A fully qualified global name is always accessable and usable from everywhere. The "problem" I think you are indirectly referring to is when you have a module X that uses globals that exist within the package that other code must then fully qualify using the full package name. For a variable named $X::x thats not so bad, but when the package is Some::Long::Package::Name it starts getting clumsy.

      The options are to export the globals in to the consumers package or to use "special globals" (like $a, $b, and $_) or to just use vars in package main. Assuming that you don't have a lot of globals in use in package main (IME a safe assumption) using such vars is IMO a reasonable choice. In other words typing $::Hash isn't so tough. Typing $Some::Long::Package::Name::Hash is.

      ---
      $world=~s/war/peace/g