in reply to Re: Permissions Utility Script for sysadmins - seeking comments
in thread Permissions Utility Script for sysadmins - seeking comments
I am getting a bit confused with one or two things and was hoping you could elucidate a bit more on what might be going on and how I might make it better. Specifically where you mention "use a hash" - I am a bit unsure on how to best impliment this in this context. Also, do you have any insight into why (as you mentioned) if there are both dir-mode and dir-owner that the latter will be silently ignored. Thanks in advance.
-Shane
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Re: Re: Permissions Utility Script for sysadmins - seeking comments
by hv (Prior) on Apr 22, 2004 at 09:09 UTC | |
Ok, here's a simplistic way to replace one of the string of elsifs with a hash:
This is simply saying: we have a string of (els)ifs, and whichever string we match we're going to execute almost the same code, so let's abstract out the one bit that varies (the variable name in this case) and let the hash associate the string to match with the variable name to modify, leaving the rest of the code constant. However, we also have a series of similar variable names, which is also often a sign that a hash is needed. So let's look at the point we're using these variables: I'd characterise the wanted_c subroutine as doing something like:
but pick one of three such structures depending on the type of file: and having made that conceptual transformation, we can now get rid of the matrix of individually named variables:
Note that you could as easily represent this data using arrays rather than hashes, but it then becomes much less self-documenting unless you also use named constants for the indexes into each array. In general, whenever I see code that needs to cope with several different cases, my instinct is to ask: what effort will be required when another new case needs to be added to the list? How far can I reduce that effort? How can I minimise the danger of getting it wrong when I need to add a new case, for example by adding it in one place and not in another? Usually, the answer is: use data structures to minimise code duplication; where possible, encapsulate all the information for the cases in a single data structure, so all the work involved in adding a new case is reduced to adding a new entry into that data structure. It may be overkill for this script, but we can take that extra step by taking advantage of code references. The data structures might then look something like this:
However, I suspect that would not be desirable, at least for the update types, since it makes it much harder to add interdependencies between the update types such as (for example) updating ownership before mode. Hugo | [reply] [d/l] [select] |
by BuddhaNature (Beadle) on Apr 22, 2004 at 18:58 UTC | |
The changes work like a charm. I have one problem and one question though. The problem is that I keep getting a diagnostic warning:
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 | [reply] [d/l] [select] |
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:
In this case, you can avoid the problem just as described:
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 | [reply] [d/l] [select] |
by BuddhaNature (Beadle) on Apr 22, 2004 at 23:44 UTC | |
|
Re: Re: Re: Permissions Utility Script for sysadmins - seeking comments
by hv (Prior) on Apr 21, 2004 at 23:07 UTC | |
Also, do you have any insight into why (as you mentioned) if there are both dir-mode and dir-owner that the latter will be silently ignored.
Update: bother, I was right the first time. See Re^5: Permissions Utility Script for sysadmins - seeking comments instead. I'll try tomorrow to come up with a couple of examples of how you might use a hash to improve things. Hugo | [reply] |
by BuddhaNature (Beadle) on Apr 21, 2004 at 23:51 UTC | |
That way it gets called as many times as is applicable to the file. Thanks for the pointer - I look forward to looking into your hash idea, which is slightly coalescing in my brain, but wouldn't mind your nudging it a bit with some advice/examples. -Shane UPDATE: This fixed the problem but created another - it is doing everything, but only on one file! I see it is because of setting the variables to "", but am kinda unsure of what to do instead... 2nd UPDATE: Things are good now except for one thing, in order to fix the problem I created
after the spot you suggest a hash. I then put
as the final part of the wanted_c function. Everything works fine now, except since I am using diagnostics I get:
Any thoughts? | [reply] [d/l] [select] |
by hv (Prior) on Apr 22, 2004 at 09:19 UTC | |
Bother, I was right the first time, and looking at the wrong bit of code the second time. The wanted_c routine is called once for each file, and in the original code it goes through a series of elsifs until it finds a match, so it will only act on the first match - the first combination of filetype and updatetype that is appropriate. So to fix it you need to avoid that; the minimal fix would probably be something like this:
The point is that the different filetypes are exclusive: you're only interested in the first type that matches, so an if/elsif chain is appropriate. The updatetypes are not exclusive: you want to act on each updatetype that is specified, so you much check each of them without jumping out on the first one. An if/elsif chain is not appropriate for that case. Hugo | [reply] [d/l] [select] |