Path: csiph.com!xmission!news.glorb.com!usenet.stanford.edu!not-for-mail From: Linda Walsh Newsgroups: gnu.bash.bug Subject: Re: language inconsistency(wart) & RFE Date: Wed, 21 Oct 2015 19:19:30 -0700 Lines: 136 Approved: bug-bash@gnu.org Message-ID: References: <5621A1DD.90205@tlinx.org> <56226F73.4040908@tlinx.org> <20151019124228.GT27325@eeg.ccf.org> NNTP-Posting-Host: lists.gnu.org Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Trace: usenet.stanford.edu 1445491712 8769 208.118.235.17 (22 Oct 2015 05:28:32 GMT) X-Complaints-To: action@cs.stanford.edu Cc: bug-bash To: Greg Wooledge Envelope-to: bug-bash@gnu.org User-Agent: Thunderbird In-Reply-To: <20151019124228.GT27325@eeg.ccf.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] X-Received-From: 173.164.175.65 X-BeenThere: bug-bash@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Bug reports for the GNU Bourne Again SHell List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Xref: csiph.com gnu.bash.bug:11738 Greg Wooledge wrote: > On Sat, Oct 17, 2015 at 08:55:31AM -0700, Linda Walsh wrote: >> If I needed a way to declare something global, yes... >> But what I am wanting is a way to allow changing the defaults >> of the implicit variable creation (which could still be >> explicitly declared with "-g" if one wanted their result to be >> made global. > > So you are basically saying you want all of your function variables > to be local --- No... only ones where 'shopt -s auto_local' was in effect. but you are too lazy to write 'local i j k' and you want > bash to do it for you? ---- local i j k doesn't define j as an array or k as a hash or g (w/-g ) as a global or any case modification vars. Not to mention your statement doesn't work: function nint { local i j k for ((i=0; i<10; ++i)) ; do j+=i; k+=j ;done echo "i=$i, j=$j, k=$k" } > nint && echo "($i, $j, $k)" i=10, j=iiiiiiiiii, k=jjjjjjjjjj (, , ) You declared them all the same, but at the end of the function, j and k do not have integer values. Trying to init them: function nint { local i=0 j=0 k=0 for ((i=0; i<10; ++i)) ; do j+=i k+=j done my -p i j k; echo "i=$i, j=$j, k=$k" } ---- nint && echo "($i, $j, $k)" declare -- i="10" declare -- j="0iiiiiiiiii" declare -- k="0jjjjjjjjjj" i=10, j=0iiiiiiiiii, k=0jjjjjjjjjj (, , ) --- Now we see that i & j & k all have the same attributes ... yet only 'i' has an integer value. If you could declare all the vars in 1 statement w/different types: declare -i INT -a ARRAY -A HASH --- That would be a huge improvement. But instead,if you use a 'for' statement, without pre-declaring all the vars used, you end up leaking variables: > function nint { for ((i=0; i<10; ++i)) ; do j+=i k+=j done my -p i j k; echo "i=$i, j=$j, k=$k" } > nint && echo "($i, $j, $k)" declare -- i="10" declare -- j="iiiiiiiiii" declare -- k="jjjjjjjjjj" i=10, j=iiiiiiiiii, k=jjjjjjjjjj (10, iiiiiiiiii, jjjjjjjjjj) --- "leaking variables" into the external environment is almost always considered bad-practice. The default that bash encourages with its default behavior is for all implicitly used vars in a function to be leaked to the global level. From a program maintenance and development standpoint, having such a horrible default with no way to override it just seems really icky. > > Also I think you are completely misrepresenting the dynamic variable > scope system that bash uses. Variables are not just global or local. > There's an entire stack of them. When you reference a variable (let's > say i) inside a function, bash searches up through the call stack > looking for a variable named i until it finds one. > > Since functions cannot return values to their callers, the entire system > of "put values into an upper-scope variable so the caller can see them" > would break if your proposal of automatic localization were to be > adopted. > > > # Pick unbiased random number from 0 to N-1 ($1 = N) > # Returns value in variable r. > rand() { > local max=$((32768 / $1 * $1)) > while (( (r=$RANDOM) >= max )); do :; done > r=$(( r % $1 )) > } > > foo() { > local r > rand 6 > echo "I rolled $((r+1))" > } > > foo > # r is not visible here > > > Under your proposal, the variable r which is defined locally in foo, and > is up-scope-visible to rand (so that rand can put a return value into > it), would also be defined locally within r, so there would be no way to > return a value from rand to foo. > > (If you want to attack "language warts", start with the inability to > return values from functions to their callers!) >