On Fri, 9 Mar 2018 11:29:35 -0500 Chet Ramey <chet.ra...@case.edu> wrote:
> On 3/7/18 3:20 PM, christopher barry wrote: > > On Wed, 7 Mar 2018 11:45:13 -0500 > > christopher barry <cba...@rajant.com> wrote: > > > > ===8<---snip > > > >> > >> I am in fact using this method with associative arrays. > >> > >> I have a default hash that is full of default values for a > >> particular generic type of thing. Variations of this thing use > >> many of the defaults, but also set some values uniquely. I could > >> simply duplicate this hash everywhere, and edit the differences, > >> but then changing any defaults would require a change everywhere. > >> > >> As an alternative, I created a template hash that all non-default > >> things start out with. > >> > >> this template hash has all of it's values pointing to > >> "default_hash[somekey]" > >> > >> new things that need to change their specific values simply > >> override that and put in their string. > >> > >> Now, changes to actual values in default_hash are seen everywhere > >> they are not overridden locally by the specific thing using it. > >> > >> so reading a hash value may be an indirect pointer to the > >> default_hash or an overridden value set by the specific thing > >> using the hash. > >> > >> ivar solves this nicely. > >> > >> > >> But to get back on point, the bug in bash was nasty, and it's > >> fantastic that it's fixed now, but throwing an error now, rather > >> than simply returning 1 with no data is a bit like throwing the > >> baby out with the bathwater. > >> > >> > >> -C > > > > Chet, > > > > Does modifying this current behavior sound like anything you would > > be willing to entertain? > > I think that throwing an error when the value of a variable used for > indirection would not be accepted as valid (and throw an error) when > used directly is the right thing to do, and I will leave it as the > default behavior. > > I'm open to suggestions about how to allow alternate behavior: a shell > option, something controlled by the shell compatibility level, > something else? It seems like you're really interested in learning > whether a particular string is a valid shell variable and doing > something based on the result. You could check that directly -- the > pattern to describe a shell variable isn't that hard to write -- but > I get the sense that you'd rather not take the extra step. > > Chet > Hi Chet, It's not that I don't want to take any required steps, it was that it seemed logical to me to simply return 1 in that instance. When I discovered that this method worked the way I was hoping, I was kinda miffed at myself for never having noticed it earlier. Then I was shown it was not working on new versions. I had never hit the core dump issue before you pointed it out. Could the fact that that bug caused a core dump be influencing why you do not want to simply return 1 now? Maybe throwing an error now seems better because it was such a bad bug before? When assigning to a var, format checking absolutely should be done, and an error should be thrown if invalid. But if only checking, e.g. just reading a name, then returning 1 if it's an invalid name or does not exist seems like the smallest, most applicable hammer for the job at hand. I did actually spend some time (longer than I would like to admit) trying to craft a decent regex to make sure that every possible way of asking was covered, but it turns out to be a bit more complex that one may think at first blush. ^([#]*(_[[:digit:]]|[_[:alpha:]])[_[:alnum:]]*)(\[[_[:alnum:]*@]+\])$ testing against ${1}, ${BASH_REMATCH[0]} and ${BASH_REMATCH[1]} would mostly show the valid forms, but this regex was still not quite right. A colleague here at work came up with a beautiful 16oz ball-peen hammer approach, no regex required, as can be seen here: #----------------------------------------------------------------------- function ivar() # Description: cascading indirect -> regular var expander { ( echo -n "${!1:-${1}}" ) 2>/dev/null || echo -n "${1}" } #--- it solves the problem, so that's what I'm using now, but it's obviously not as clean and simple as it was, and it can still core dump the sub-shell, which does suck, but it's non-fatal. If you can't see my point about not needing to throw an error on just a read, then I guess I'll just have to deal with it. Thanks, and maybe you will come to see my position at some point, never know :) Regards, -C