Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Re^3: Why $FIle::Find::prune = 1 returns used only once error

by h2 (Beadle)
on Apr 16, 2021 at 23:02 UTC ( [id://11131397]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Why $FIle::Find::prune = 1 returns used only once error
in thread Why $FIle::Find::prune = 1 returns used only once error

I found a way to trick the Perl compiler into not complaining, though I suspect this may be a bug but that's also not something I can fix or correct, the solution proved to be quite simple:

$File::Find::prune = 1 if defined $File::Find::prune;

I'd definitely put this in the category of a hackish fix, but it's easy to do, and worked, and didn't take any convolutions so I guess it's good enough. Hopefully anyone in the future who comes across this issue can resolve the problem with this simple trick. Since $File::Find::prune wont' be defined prior to require File::Find being run, perl doesn't care about it when it's checking the code on start, and since when this feature runs, File::Find::prune is defined, it works as expected. Not super intuitive, obviously, but there you have it, a fix, that works!

Replies are listed 'Best First'.
Re^4: Why $File::Find::prune = 1 returns used only once error
by haukex (Archbishop) on Apr 18, 2021 at 10:57 UTC
    $File::Find::prune = 1 if defined $File::Find::prune;

    Careful, I doubt this actually does what you think! None of the versions of File::Find that I looked at set prune to a defined value, meaning your code may silence the warning but wouldn't actually set $File::Find::prune to a true value! The code would only work if some piece of code somewhere was setting $File::Find::prune to some value other than undef, but you probably don't want to depend on that happening.

    Since $File::Find::prune wont' be defined prior to require File::Find being run, perl doesn't care about it when it's checking the code on start, and since when this feature runs, File::Find::prune is defined, it works as expected.

    Based on your wording here I think there may be a misunderstanding as to what defined does. File::Find says our $prune;, thus letting the variable be known to the compiler, but it still leaves the variable's value at undef, which is what defined tests - i.e. your test above will still be false.

Re^4: Why $FIle::Find::prune = 1 returns used only once error
by h2 (Beadle) on Apr 18, 2021 at 19:37 UTC

    Re the comments, don't know how to reply to them:

    Obviously I was concerned that:

    $File::Find::prune = 1 if defined $File::Find::prune;

    would never execute, since that would not solve the issue I had had, but this is not correct, it executes fine, just tested it, printed out a test, say, you are running File::Find::find on /, and exclude /dev /etc/ /var /run etc, then print out inside the test block $File::Find::name and it works exactly as expected, first match, the directory, prune is set to 1, then never prints again for that directory. So apparently prune does get defined somewhere or other, though I'm not going to guess at the innards of Perl, lol, but I can confirm that my trick worked, at least in current Perl.

    Testing the two methods, they are identical in outcome, but given that the prune defined test may be uncertain across Perls, I'm going with the safer one, that will always work without depending on if prune had been defined or not when File::Find was imported. Empirically, it is defined, but I'm going to assume it may not always have been defined in the past (however, that past would have to be long ago, because I tested this on Perl 5.008 with no issues). This makes sense, but from my test, I'd then guess that prune is set to 0, not undefined, per directory, until told otherwise. It must be that otherwise, as you suggested, it would never have worked. I know I make this choice all the time, whether to use an explicit boolean 0/1, or to use undef/1, clearly prune uses 0/1.

    As noted, however, it was the simple use of $File::Find::prune twice that made the warning go away, so it's probably safer to just use:

    $File::Find::prune = 1; $File::Find::prune = 1;

    even though as code it looks really odd, but that also worked fine, and made the interpreter not issue its warning.

    Or, maybe looking a bit less odd:

    $File::Find::prune = 1 if !$File::Find::prune;

    This would I assume remove the possibility that the behavior I got with the defined test might not be general to all Perl versions, which would be a problem. All of these however work exactly the same empirically, but given there may be a Perl where in fact prune was not initially defined, that's risky, and given using prune = 1 2x looks silly in the code, I'm going with the if ! $File::Find::prune test

    However, in the end, I realize now that once I got the first warning out of the way, I added in a second use of prune in a different block, which then of course made the warning go away, so it turns out I never needed the first fix at all, I just didn't realize what was making the warning happen clearly enough.

    Thanks for the comments and observations, they were helpful.

Re^4: Why $FIle::Find::prune = 1 returns used only once error
by jcb (Parson) on Apr 18, 2021 at 02:30 UTC

    The Perl compiler is complaining that it only saw File::Find::prune once, so you solve the issue by having your program mention File::Find::prune twice. The warning is intended to catch "odd man out" typos in variable names.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11131397]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2024-04-25 19:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found