Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7092841
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T08:21:53+00:00 2026-05-28T08:21:53+00:00

Given a root directory I wish to identify the most shallow parent directory of

  • 0

Given a root directory I wish to identify the most shallow parent directory of any .svn directory and pom.xml .

To achieve this I defined the following function

use File::Find;
sub firstDirWithFileUnder {
    $needle=@_[0];
    my $result = 0;
    sub wanted {
        print "\twanted->result is '$result'\n";
        my $dir = "${File::Find::dir}";

        if ($_ eq $needle and ((not $result) or length($dir) < length($result))) {
            $result=$dir;
            print "Setting result: '$result'\n";
        }
    }
    find(\&wanted, @_[1]);
    print "Result: '$result'\n";
    return $result;
}

..and call it thus:

    $svnDir = firstDirWithFileUnder(".svn",$projPath);
    print "\tIdentified svn dir:\n\t'$svnDir'\n";
    $pomDir = firstDirWithFileUnder("pom.xml",$projPath);
    print "\tIdentified pom.xml dir:\n\t'$pomDir'\n";

There are two situations which arise that I cannot explain:

  1. When the search for a .svn is successful, the value of $result perceived inside the nested subroutine wanted persists into the next call of firstDirWithFileUnder. So when the pom search begins, although the line my $result = 0; still exists, the wanted subroutine sees its value as the return value from the last firstDirWithFileUnder call.
  2. If the my $result = 0; line is commented out, then the function still executes properly. This means a) outer scope (firstDirWithFileUnder) can still see the $result variable to be able to return it, and b) print shows that wanted still sees $result value from last time, i.e. it seems to have formed a closure that’s persisted beyond the first call of firstDirWithFileUnder.

Can somebody explain what’s happening, and suggest how I can properly reset the value of $result to zero upon entering the outer scope?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T08:21:54+00:00Added an answer on May 28, 2026 at 8:21 am

    Using warnings and then diagnostics yields this helpful information, including a solution:

    Variable “$needle” will not stay shared at —– line 12 (#1)

    (W closure) An inner (nested) named subroutine is referencing a
    lexical variable defined in an outer named subroutine.

    When the inner subroutine is called, it will see the value of
    the outer subroutine’s variable as it was before and during the first
    call to the outer subroutine; in this case, after the first call to the
    outer subroutine is complete, the inner and outer subroutines will no
    longer share a common value for the variable. In other words, the
    variable will no longer be shared.

    This problem can usually be solved by making the inner subroutine
    anonymous, using the sub {} syntax.
    When inner anonymous subs that
    reference variables in outer subroutines are created, they
    are automatically rebound to the current values of such variables.


    $result is lexically scoped, meaning a brand new variable is allocated every time you call &firstDirWithFileUnder.
    sub wanted { ... } is a compile-time subroutine declaration, meaning it is compiled by the Perl interpreter one time and stored in your package’s symbol table. Since it contains a reference to the lexically scoped $result variable, the subroutine definition that Perl saves will only refer to the first instance of $result. The second time you call &firstDirWithFileUnder and declare a new $result variable, this will be a completely different variable than the $result inside &wanted.

    You’ll want to change your sub wanted { ... } declaration to a lexically scoped, anonymous sub:

    my $wanted = sub {
        print "\twanted->result is '$result'\n";
        ...
    };
    

    and invoke File::Find::find as

    find($wanted, $_[1])
    

    Here, $wanted is a run-time declaration for a subroutine, and it gets redefined with the current reference to $result in every separate call to &firstDirWithFileUnder.


    Update: This code snippet may prove instructive:

    sub foo {
        my $foo = 0;  # lexical variable
        $bar = 0;     # global variable
        sub compiletime {
            print "compile foo is ", ++$foo, " ", \$foo, "\n";
            print "compile bar is ", ++$bar, " ", \$bar, "\n";
        }
        my $runtime = sub {
            print "runtime foo is ", ++$foo, " ", \$foo, "\n";
            print "runtime bar is ", ++$bar, " ", \$bar, "\n";
        };
        &compiletime;
        &$runtime;
        print "----------------\n";
        push @baz, \$foo;  # explained below
    }
    &foo for 1..3;
    

    Typical output:

    compile foo is 1 SCALAR(0xac18c0)
    compile bar is 1 SCALAR(0xac1938)
    runtime foo is 2 SCALAR(0xac18c0)
    runtime bar is 2 SCALAR(0xac1938)
    ----------------
    compile foo is 3 SCALAR(0xac18c0)
    compile bar is 1 SCALAR(0xac1938)
    runtime foo is 1 SCALAR(0xa63d18)
    runtime bar is 2 SCALAR(0xac1938)
    ----------------
    compile foo is 4 SCALAR(0xac18c0)
    compile bar is 1 SCALAR(0xac1938)
    runtime foo is 1 SCALAR(0xac1db8)
    runtime bar is 2 SCALAR(0xac1938)
    ----------------
    

    Note that the compile time $foo always refers to the same variable SCALAR(0xac18c0), and that this is also the run time $foo THE FIRST TIME the function is run.

    The last line of &foo, push @baz,\$foo is included in this example so that $foo doesn’t get garbage collected at the end of &foo. Otherwise, the 2nd and 3rd runtime $foo might point to the same address, even though they refer to different variables (the memory is reallocated each time the variable is declared).

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

given this xml: <root> <list> <!-- foo's comment --> <item name=foo /> <item name=bar
Say I have this given XML file: <root> <node>x</node> <node>y</node> <node>a</node> </root> And I
I have a xml given below: <root title=الصفحة الرئيسة> <item title=الصفحة الرئيسة itemuri=tcm:8-29-4 ShowInNav=True
How can I know if a given directory is a root drive? (aside from
Given a group like this in Active Directory: MainGroup GroupA User1 User2 GroupB User3
Most programming languages give 2 as the answer to square root of 4 .
Given a Python object of any kind, is there an easy way to get
How to dynamically generate a fileset based on user input? Given this directories :
When installing subversion as a service, I used this command: c:\>svnservice -install --daemon --root
I have this piece of code that searches for a folder given a starting

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.