Path: csiph.com!goblin1!goblin.stu.neva.ru!usenet.stanford.edu!not-for-mail From: Binarus Newsgroups: gnu.bash.bug Subject: Re: Incorrect / Inconsistent behavior with nameref assignments in functions Date: Fri, 28 Aug 2020 18:20:04 +0200 Lines: 79 Approved: bug-bash@gnu.org Message-ID: References: <20200828152846.GI931@eeg.ccf.org> <5ad2613b-c2d4-d774-fbfb-eec77770b014@binarus.de> NNTP-Posting-Host: lists.gnu.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Trace: usenet.stanford.edu 1598631612 8299 209.51.188.17 (28 Aug 2020 16:20:12 GMT) X-Complaints-To: action@cs.stanford.edu To: bug-bash@gnu.org Envelope-to: bug-bash@gnu.org X-Envelope-To: DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=binarus.de; s=b201601; t=1598631603; bh=ByrbRQP1MY/PzF92b4qAo1GN2AT0Ot97XNXaET3e91A=; h=Subject:To:References:From:Date:In-Reply-To:From:Reply-To:Subject: Date:To:Cc:Resent-Date:Resent-From:Resent-To:Resent-Cc:In-Reply-To: References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; b=rvMAhyAbU0T8sEy6un7jMkqRUFcSKqmFk3MvUY/82I2Qk2b6c0aVntSwfwcImBZXC yStbIOzzudeoh3h2cutuIZkNER1bMc9ix251rbqK6pc0TsTaiVRTbkAynZWPrt+mic nhcm0MYRef5cVsvfkBA6LNpk3LlWQUZk4XHFtvwVrgQxlfXslLHGhuzOISu5m1kbBI zRd8UHqkQT//nORLJWFw12fVQWIhZa3gZcwjt8GTJ4YYqHvR4rScrVtMootw7NeMxb 3QiwHy/La13uASpJjE359A0JzbgTENytGMQ//envA5BHNLcvkFTYnKbKO8NC4tf0bF fTbiWGT5/w3Fvl2Au2mjJPhs1YSms6lPr427kIJXnluStxjdlWaqbucuA4Q9Sf9/1+ Iu7KI0GZU1MVkmT/DOZ69VYepeoPc3ZhNW/kVPEW89gvoPqDvrJJSGPdke7Q1rsGmg NBMEYzKhBi4aXwez2YUb2i3l9GhTm6rw6tj18rTDcvvIYHFjhPyKEthGfEhUDFjX+I 4IDNgM1nqd1KiVhQtAZRSMvkAprLEVrZ+ykB7CdZwgCw/20yzPXlAuCoMWad3F6RrQ Nk/5sEYRaknJ4LL5d6xf/F8Tlk9EtLbff49+2WuUdcflzzxQvGd2I03+aA6ePhO1I6 IT4g2nXbDDWS4tVKmDsKWLe0= User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Thunderbird/68.9.0 In-Reply-To: <20200828152846.GI931@eeg.ccf.org> Content-Language: en-US X-Bin-MAIL-FROM: X-Bin-RCPT-TO: Received-SPF: pass client-ip=144.76.90.229; envelope-from=lists@binarus.de; helo=odysseus.binarus.de X-detected-operating-system: by eggs.gnu.org: First seen = 2020/08/28 12:20:04 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, NICE_REPLY_A=-0.809, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: bug-bash@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Bug reports for the GNU Bourne Again SHell List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Mailman-Original-Message-ID: <5ad2613b-c2d4-d774-fbfb-eec77770b014@binarus.de> X-Mailman-Original-References: <20200828152846.GI931@eeg.ccf.org> Xref: csiph.com gnu.bash.bug:16832 On 28.08.2020 17:28, Greg Wooledge wrote: > On Fri, Aug 28, 2020 at 10:56:34AM +0200, Binarus wrote: >> #!/bin/bash >> >> function Dummy() { >> >> local -n namerefArray="$1" >> local -a -i myArray=("${namerefArray[@]}") >> >> local -p >> } >> >> declare -a -i myArray=('1' '2' '3') > > You've got a local variable with the same name as the global variable > that you're attempting to pass by reference. This will not work. > > Namerefs (declare -n) in bash are *not* like uplevel commands in Tcl. > They cause the referenced variable name to be evaluated just like any > other variable would be, starting at the current function scope, then > going up to the caller, and so on. > > If you want to use namerefs in a function in bash, you MUST go out of > your way to minimize the chances of a collision between the caller's > variable refererance and ANY local variable of the function. Not just > the nameref itself, but any other incidental variables used in the > function. (As you aptly demonstrated here.) > > So, you can't write functions like this: > > func1() { > declare -n ref="$1" > local i > ... > } > > Instead, you need crazy things like this: > > func1() { > declare -n _func1_ref="$1" > local _func1_i > ... > } I had worked that out myself so far and have setup a naming convention in my script similar to your proposition before posting the bug. I needed a while to recognize the problem since I wouldn't have expected it because it renders namerefs nearly useless. However, the main question is why leaving away the -a and -i in the second script makes things work as expected. Can we rely on that behavior and circumvent the problem that way? Both scripts should give the same output, shouldn't they? So it's a bug they don't, and we can't rely on it? For reference, I also have posted a question about it on SO yesterday (nicer code formatting): https://stackoverflow.com/questions/63629172/weird-behavior-when-assigning-local-namerefs-to-local-variables-in-functions?noredirect=1#comment112528357_63629172 > And then you just have to pray that the caller respects you enough not > to use variables named with _func1_ prefixes. > > There is no 100% bulletproof solution to this issue. > > See also . Since I am the caller :-), this won't impose a problem. I have excessively commented that script. However, this whole thing does not make much sense. I have put too much work into this script; otherwise, I'd dump it and restart with Perl or Python. Thank you very much, and best regards, Binarus