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

Hi all,

If I am just missing an FAQ, please forgive me, but I didn't see this in either the Q&A or via Supersearch.

I have many many subs in my program, many called sequentially, or from within other subs. Some of these down-the-line subs require inputs from the output of a sub 5 or 6 places back up the line. i.e.

sub First { # do something.... return $info_required_not_until_sub_seven; } sub Seventh { my $input_from_first = shift; my $input_from_fourth = shift; my $input_from_sixth = shift; #etc... }
What I've been doing so far has been passing the variable through each and every intervening sub. I had originally made them global rather than scoped to each individual sub, but many people were suggesting that was a big drain on memory, esp since some of these are huge arrays, etc.

My question is, is there a way to hold on to a locally scoped variable, to pass it on later, or even something along the lines of :

from sub FIRST get $input_required_not_until_seventh
?

Thanks,
Matt

Replies are listed 'Best First'.
Re: Getting variables from mulitple subs at once?
by ikegami (Patriarch) on Feb 19, 2007 at 17:36 UTC

    You could use globals.

    my $first; my $second; my $third; sub First { ... } sub Second { ... } sub Third { ... } { $first = First(); $second = Second(); $third = Third(); }

    You could use dynamically bound variables.

    sub First { ... } sub Second { our $first; ... } sub Third { our $first; our $second; ... } { local our $first = First(); local our $second = Second(); local our $third = Third(); }

    A variation on the last one:

    our $first; our $second; our $third; sub First { ... } sub Second { ... } sub Third { ... } { local $first = First(); local $second = Second(); local $third = Third(); }

    You could use an object:

    sub First { ... } sub Second { ... } sub Third { ... } { my $o = ...; $o->First(); $o->Second(); $o->Third(); }

    You could use a hash:

    sub First { ... } sub Second { ... } sub Third { ... } { my %h; First(\%h); Second(\%h); Third(\%h); }

    In your particular case, I'd probably go with "A variation on the last one". It uses global variables, but they get cleared at the end of the curlies in which the local statements are located.

      Thanks ikegami,

      At the moment, I think I'll try out philcrow's data hash idea. If that winds up not quite working right, I'll give your suggestions a try. Thanks though.

      Matt

Re: Getting variables from mulitple subs at once?
by philcrow (Priest) on Feb 19, 2007 at 17:30 UTC
    If arrays are large, pass them as references (\@arrayname). If intervening subs have no use for the data they are passing through, consider a data hash which everyone would pass around. Subs would look in the hash for the data they need to do their work and would place there answers there as well.

    Phil

      Thanks Phil

      I had been thinking about maybe making a data hash. At first, I was wary, as it could possibly have grown to be very large, but on thinking more about it, I can discretely separate the large data structures from the smaller ones, and pass the larger ones far less frequently. So, that might just be what I need.

      Matt

Re: Getting variables from mulitple subs at once?
by ferreira (Chaplain) on Feb 19, 2007 at 17:33 UTC
    My question is, is there a way to hold on to a locally scoped variable, to pass it on later

    I think that a solution to the question you formulated will, in the long time, cause you more problems than it solves. Global variables are bad (most of the time). Abuse of local variables hurts. Strange dependencies to nesting depth of sub invocations will probably be naughty.

    I think two sane approaches could be:

    • use closures,
    • reformulate the algorithm, passing meaningful objects or at least data structures with the fields/attributes you will need.

    The solution with closures involves defining subs inside subs and accessing, when you need, variables of an upper lexical scope. The other involves decreasing the number of variables by stuffing the values into fields/attributes of objects/structures that make sense to the problem at hand and accessing them wisely.

      Thanks for the thoughts. I'll try to read more about closures, as I am not sure I understand. I'll give it a look though. As for reforumlating the algorithm, I have reworked it numerous times, and believe me or not, this is by far the most logical and sane version.

      Matt