On Mon, Apr 8, 2013 at 9:05 PM, Greg Wooledge <wool...@eeg.ccf.org> wrote:
> On Fri, Apr 05, 2013 at 09:15:10AM +0800, konsolebox wrote: > > The only thing left here is that we can't have error control like when we > > are to create generally shared library scripts e.g.: > > > > function lib_something { > > declare -n VAR=$1 &>/devnull || { # error message is not suppressed > > : can_t go here if referred variable's name is invalid > > return 1 # or do other things like proper error messaging > > } > > VAR["XYZ.1324"]="Some Value." &>/dev/null || { # error message is not > > suppressed > > : can_t go here if referred variable is not of associative array > > type > > return 1 # or do other things like proper error messaging > > } > > } > > For the first part: you can check that "$1" is a valid identifier before > you do the declare. > I considered that but I don't think it would be a good idea to check +([[:alpha:]_])*([[:alnum:]_) on every function that uses that. But anyway it doesn't really matter since it's only about variable names and this would apply if we have setvalue as well, only that if we are to control error messages this check would have been optional for setvalue. With declare, we can't control the error message. > For the second part: you appear to be correct: you can't reliably > determine what the nameref is pointing to in all cases. If the upstream > variable has a value assigned, then you can; but if it's empty, then you > can't. > > imadev:~$ libbar() { declare -n x=$1; declare -p x; } > imadev:~$ unset foo > imadev:~$ libbar foo > bash-4.3: declare: x: not found > imadev:~$ declare -a foo > imadev:~$ libbar foo > bash-4.3: declare: x: not found > imadev:~$ foo=(some stuff) > imadev:~$ libbar foo > declare -a foo='([0]="some" [1]="stuff")' > imadev:~$ declare -A bar > imadev:~$ libbar bar > bash-4.3: declare: x: not found > imadev:~$ bar[x]=q > imadev:~$ libbar bar > declare -A bar='([x]="q" )' > > There may be some clever way to determine whether the upstream variable > is an associative array or not, but I can't think of one right now. > We're getting far with that already. And I don't think there would be other more clever tricks besides encapsulation hacks which are rather messy. Another case also is if we're actually implying to set an associative array variable, and one of the keys provided for it from a variable source appeared to be numeric, then the assignment would be accepted even though it should really have been invalid. An explicit assignment could be done with setvalue -A. Also, please consider using "()" instead of "function" when defining > functions. Bash may support both, but POSIX only requires "()". > I intended to use function {} since that's my standard for bash-based scripts sorry. I find it more consistent with the declaration. I do use () if it's sh-based. And I don't really follow POSIX if I'm after compatibility. As long as I see generic compatibility among shells it would be enough. Not all shells strictly follow POSIX after all. And POSIX is not the first but sh. POSIX also I think has many versions. Ross