On Sat, Oct 15, 2016 at 7:58 PM, Marco Ippolito <maroloc...@gmail.com> wrote: > On Sat, Oct 15, 2016 at 07:32:23PM +0800, konsolebox wrote: >> On Sat, Oct 15, 2016 at 11:12 AM, Marco Ippolito <maroloc...@gmail.com> >> wrote: >> > Bash has elegant and powerful constructs like `mapfile', >> > yet it is missing something as easy as an array "pop". >> > >> > Extract the last value of an array at the same time as >> > removing it from the array. >> > >> > Is this the best one can do? >> > >> > $ a=(1 2 3); v=${a[-1]}; unset 'a[-1]'; printf '%s\n' "$v" "${a[@]}" >> > >> > The 2-step approach gets tiresome after a while. >> > >> > For positional parameters, it _does_ have `shift'... >> > ... maybe it could add a `pop`, somehow? >> > >> >> Since you're using Bash-4.3 (or 4.4), you can create a function that >> uses declare -n: >> >> $ function array_pop { declare -n __a=$1; __=${__a[-1]}; unset '__a[-1]'; } >> $ a=(1 2 3); array_pop a; printf '%s\n' "$__" "${a[@]}" >> 3 >> 1 >> 2 >> >> And my simple rule to using functions that process variables with -n: >> don't pass variables that begin with two underscores. There's another >> way to avoid variable name conflicts, and that is to prefix the >> reference variables with the name of the function itself, but I find >> that already an overkill. >> >> You can also improve the function by adding sanity checks, but that's >> the basic concept of it. >> >> -- >> konsolebox > > Nice function but there is something I dislike about it. > > I find the alteration of global state as a side-effect in contradiction with > the notion of self-containment of functions, e.g.: > > $ unset x; printf '|%s|\n' "$x"; f() { x=y; }; f; printf '|%s|\n' "$x" > || > |y| > > > The potential overwriting of a pre-existing identifier `__' is, in my eyes, > undesirable. > > Shouldn't I be able to call a function without worrying about what it could do > to my current scope? (This may be a debatable point for some).
Oh so you actually meant my use of __. Sorry I just got used to that practice. I treat __ as a "volatile global variable" i.e., one should expect that it can change on every call to another function. I prefer things done that way since it's more efficient, and/or is more doable in older versions of bash. This time I use it as a result variable, but sometimes I use it as a common "iterator", or just a temporary variable. You can follow lolilolicon's suggestion if you want to pass another variable that would store the value instead. My version would be this: function array_pop { declare -n __a=$1 __v=$2; __v=${__a[-1]}; unset '__a[-1]'; } By the way, please use "Reply to all" so your message would also be sent to bug-bash. You can also have that configured in Gmail so that it would be the default behavior. -- konsolebox