Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: Re: Re: Re: Permissions Utility Script for sysadmins - seeking comments

by BuddhaNature (Beadle)
on Apr 22, 2004 at 18:58 UTC ( [id://347458]=note: print w/replies, xml ) Need Help??


in reply to Re: Re: Re: Permissions Utility Script for sysadmins - seeking comments
in thread Permissions Utility Script for sysadmins - seeking comments

So I took your advice and made the following changes:

my %wanted; my %validfile = map +($_ => 1), qw/ dir file link /; my %validupdate = map +($_ => 1), qw/ mode owner group /; for (keys %{ $config{$test}{$tester} }) { my($filetype, $updatetype) = split /-/, $_, 2; unless ($validfile{$filetype} && $validupdate{$updatet +ype}) { warn "Unexpected directive '$_'"; next; } $wanted{$filetype}{$updatetype} = $config{$test}{$test +er}{$_}; } [...] sub wanted_c { print "wanted_c is working on $_\n"; my %wanted_prev = %wanted; my $wanted_here; stat($_); if (-d $_) {$wanted_here = $wanted_prev{'dir'}} elsif (-l $_) {$wanted_here = $wanted_prev{'link'}} elsif (-f $_) {$wanted_here = $wanted_prev{'file'}} else {return;} return unless $wanted_here; # nothing to change print Dumper($wanted_here); if (defined $wanted_here->{'mode'}) { change_mode($_, $wanted_here->{'mode'}) + } if (defined $wanted_here->{'owner'}) { change_owner($_, $wanted_here->{'owner'}); } if (defined $wanted_here->{'group'}) { change_group($_, $wanted_here->{'group'}); } }

The changes work like a charm. I have one problem and one question though. The problem is that I keep getting a diagnostic warning:

Variable "%wanted" will not stay shared at permmy7.pl line 317 (#1)

I am a little unsure about how best to go about getting rid of it. Can't _really_ see an easy way to sub something out...

The question I have is, previously I was having issues with the file/directory/link being checked by the wanted_c function hitting only one if and then returning, so I had to toss in some recurssion - why doesn't that problem occur with the above code? I am just not seeing it and it is bugging me. It works and I am thankful for that but I want to know _why_ it works... Thanks in advance.

-Shane

Replies are listed 'Best First'.
Re^5: Permissions Utility Script for sysadmins - seeking comments
by hv (Prior) on Apr 22, 2004 at 22:51 UTC

    The problem is that I keep getting a diagnostic warning:

    Variable "%wanted" will not stay shared at permmy7.pl line 317 (#1)

    The description from diagnostics (search in perldoc perldiag, or run the script with perl -Mdiagnostics) describes what is happening here:

    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.

    In this case, you can avoid the problem just as described:

    my $wanted_c = sub { print "wanted_c is working on $_\n"; ... etc ... }; File::Find::find({wanted => $wanted_c}, $tester);

    The question I have is, previously I was having issues with the file/directory/link being checked by the wanted_c function hitting only one if and then returning, so I had to toss in some recurssion - why doesn't that problem occur with the above code?

    Recursion was not likely to be the right solution to this problem - it was not that wanted_c was only called once, but that within that one call the chain of elsif tests ensured that only one test could ever match. See another response for my suggested solution to that.

    You'll see, I hope, that the solution there and the new code are effectively the same - we only want to match one filetype, so we check for possible filetypes with a chain of elsif tests; we want to match all of the defined updates, so we use a sequence of if tests.

    Hugo

      You nailed it on the head, thanks! A friend pointed me to this link for info about the problem of closure (in case others are interested).

      (light bulb goes on - brightly) Now I see - it is the difference between the chain of if's vs. the chain of elsif's. Geez learned a real lesson there, thanks. Thanks for all the help.

      Would it be "bad form" for me to post my completed script in the Code Catacombs, or should I just update it here?

      -Shane

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2024-04-24 04:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found