On Sun, Dec 7, 2014 at 7:24 AM, Stephane Chazelas <stephane.chaze...@gmail.com> wrote: > $ b='($(uname>&2))' bash -c 'a=(); declare -r a=$b' > Linux
I actually also don't like that form of implementation. Even if declare is a builtin and not a reserved word, it still has some special treatments that's different from a simple command. For example in a simple command like echo, something like 'echo a=(1 2 3 4)' would cause syntax error. Word splitting and pathname expansion also doesn't happen unless when assigning elements in an array. If declare is able to recognize assignments separated by spaces, I think it would have not been difficult avoiding $b to be evaluated since it's really not meant to be. It clearly is a simple form of assignment. Imo even if declare is a builtin (which is actually a little special over a normal one), it should have just emulated behavior of normal assignments and did nothing more than it besides declaring the type (and optionally have some other features not related to assignment). (But I think those who used to recommend using declare as a general tool for assigning values remotely over evil eval would love it since it makes assignments like `declare -g "$var=$something"` possible which naturally should have been illegal.) Anyhow, this problem would only happen if a variable in a specific scope (and only in that scope) has already been set previously as an array and it doesn't always happen if you write your scripts well. > It may be worth recommending people do a "unset var" before > doing a "declare [-<option>] var" I actually find it better to mention that on a simple assignment like declare var=$something, var's type doesn't change if it has already been declared previously as an array. As for the unusual evaluation of $b, I believe that that implementation should be changed and it's not enough to just warn users about it. > (though in > that case one may argue that they should use their own context > and make sure they don't call other functions that modify > variables in their parent context or be aware of what variables > the functions they call may modify (recursively)). And to add, if a script is meant to be sourced, it should make sure that no unshared variable is still set after its execution ends. If it has to have variables that are meant to remain after it is sourced, then it should make sure that those variables use their own namespaces like having a prefix. As a shared script it is natural to avoid conflicts with variables of other scripts that would call you. This is always something you would always do whether declare is badly implemented or not. Shared functions otoh should be responsible of making sure that their work variables are placed as local. This is also a common practice. As for shared variables that would contain the results of the function, those that are meant to contain array values should only contain array values, and those non-array variables should always have non-array values e.g. __A0 for array and __ for non-array. Cheers, konsolebox