I'm having a hard time explaining this problem and having spent the weekend reading about closures and nested subroutines hasn't helped, I'm afraid.

Last week I received great advice here about using dispatch tables so I could add more command line initiated actions to my script.

Currently my script operates in a linearly fashion from top to bottom and has one main thing it does. I have all of my subroutines at the bottom and to put together the script I just call subroutines and walk through the individual tasks I want to complete until done.
I was thinking that in order to use dispatch tables all I should do is put my current script inside a new major subroutine which would continue to call other existing minor subroutines as it does now. Then I would eventually add additional major subroutines and pick and choose from the minor subroutines to complete that action until done.

The problem is that when I put my main script in a subroutine I get all kinds of "Variable $x will not stay shared at script.pl line nnn" errors.

- Is there a rookie friendly way to wrap my current script in a subroutine and not get the "Variable will not be shared" error?

The research I've done leads me to anonymous subroutines, closures, and much confusion. This example below isn't really the best example without including my whole script but it might be a good enough example because of the subroutine reference of File::Find \&wanted and it does give me the same error. There are several issues I'm dealing with in this example.

#!/usr/bin/perl use strict; use warnings; use File::Find; my %actions_hash = define_actions(); if (!defined @ARGV ) { @ARGV = "-h"; } my $action = shift; # First argument my @args = @ARGV; # Remaining arguments if (exists $actions_hash{$action}) { $actions_hash{$action}->(@args); } else { $actions_hash{_default_}->(@args); } sub define_actions { return ( '-f' => \&findfile, ); } sub findfile { my $target = $args[0]; my $location = "/tmp/dir1"; my $filename = find \&wanted, "$location"; sub wanted { (my $foundfile = $File::Find::name) if $File::Find::name =~ $t +arget; return $foundfile; } print $filename; }
  1. How to get rid of the "Varable will not be shared" errors? Either in my main script or maybe here and I can attempt to apply the knowledge globally to my script.
  2. How to get the $foundfile out of the wanted() subroutine?

For the record I've looked at the tutorials here but can't seem to apply the knowledge to my script.
Thank-you for your consideration.


In reply to Adding a dispatch table and getting "Variable $x will not stay shared" errors. by gctaylor1

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.