On 2/17/11 9:49 AM, Steven W. Orr wrote: > On 2/16/2011 11:08 PM, Clark J. Wang wrote: >> On Thu, Feb 17, 2011 at 11:13 AM, Chet Ramey<chet.ra...@case.edu> wrote: >> >>>> If I declare a variable at the top scope using -r, it will prevent me >>>> from declaring a local copy in a subroutine. This problem happens in >>>> this version of bash as well as in bash4 under Fedora 14. >>> >>> This is intentional. A variable is declared readonly for a reason, and >>> readonly variables may not be assigned to. I don't believe that you >>> should be able to use a function to circumvent this. >>> >>> That makes little sense to me. I don't see any disadvantages if a local var >> is allowed to use the same name as a global readonly var. And with current >> bash behavior we may see var name collisions even with the local keyword. >> >>> Chet > > I'd like to agree with Clark. I agree that a variable is declared readonly > for a purpose, but the act of declaring any variable in a subroutine must > explicitly mean that it is a different instance than any other instance.
I agree, to a point, but shells don't behave this way today. Even the mini-scope created by assignments preceding a command rejects assignments to readonly variables. (That point isn't enough to make me change the bash behavior.) > If I declare an outer scope variable as an array or an integer, why should > that be treated any differently than if it's declared as readonly? Because part of the semantics of a readonly variable include the fact that it may not be assigned to. Arrays and integers may be assigned to at will. I do > understand that a type like int or container declaration like array is > different from a readonly attribute, but either way, it's just a part of > the implementation of a scoped symbol table.) Internally, we either have > scoped symbol tables or we don't. Worst case scenario, it would be easy > (whatever that means) to write a bash lint function that would warn about a > global readonly variable that is shadowed by a variable of the same name in > a function. This is just an implementation detail. I fall on the side of security and consistency here. If a script author declares and assumes a variable is readonly, it seems best to not allow that to be circumvented simply by declaring a shell function. (If you want to circumvent it, write a shell script and create an entire new execution environment -- the readonly attribute does not survive the environment.) Consider a quick, contrived example: an administrator writes a shell package (library, set of functions, whatever) that includes, among other things, ways to make sure that some other package is invoked with a particular set of arguments and environment. He does this in part by declaring some variables readonly. Programs invoked by this package change their behavior depending on the value of environment variables, so it's important to the correct operation of this script that the variables don't change. It should be harder to cirvumvent this, possibly creating a security hole, than just declaring a shell function with a local variable that then calls a public function that expects the variable to have some other value. > > Just for context, I'm at a place that has maybe 100K lines of hack'n'wack > bash code that was written by the usual crowd of people who only mostly > knew minimal Bourne shell where everything is a self contained monolithic > structure. I'm trying to refactor this nightmare so that we can create > common libraries of subroutines, common libraries of global variables for > project specific purposes, an some of those globals need to be readonly. > When people write subroutines and declare a local variable, they should not > need to go through a clearing house to see if a name is safe to use > locally. If they *don't* declare it, then (and only then) they should > expect to bump into any predefined global variable. The idea is that not > declaring a variable in a function is the same as creating a global. This is a software engineering problem, not a variable scoping issue. The best thing to do is to define and adopt a naming convention for function names, global variables, and (if desired) local variables. The GNU coding standards for libraries might provide some guidance here. If a user of your function library is guaranteed that all of your global readonly variables start with `GRO_', for instance, he can safely declare local variables. > Have a swayed your thinking? Not enough. > And BTW Chet, you're high on my list of people who have made a non-readonly > global impact on the world. :-) :-) Chet -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, ITS, CWRU c...@case.edu http://cnswww.cns.cwru.edu/~chet/