Re: Is there a POSIX compliant way of turning a "HH:MM:SS" formatted string to seconds? ...
On Fri, Jul 18, 2025 at 12:34:36 +0200, Michael wrote:
> On Friday, July 18, 2025 12:52:03 AM CEST, Greg Wooledge wrote:
> > As far as the code goes, I'd rather start from scratch.
>
> just out of curiosity:
>
> i don't like fix global return values (like $r in your code). i'd rather
> give the function a variable name to put the result in.
>
> do you have any objections to doing this in bash?:
> ========================================================================
> #!/bin/bash
>
> # $1: name of variable to put the result in
> # $2...#n: parameters optional for whatever the function does
> myfunc ()
> {
> # do something... or not...
>
> printf -v "$1" "%s..." "..." ...
> }
Bash 4.3 and higher have nameref variables, so you could also do
something like:
myfunc() {
local -n ret="$1"
local a b c
a=... b=... c=...
ret=$((a*b + c))
}
The advantage of nameref variables is that they can also refer to
arrays as well as strings. If you need to return an array, this is
the way you'd want to go (unless you're targeting older systems).
Both ways work, with one important caveat. If the function doesn't use
any local variables at all, then these approaches work perfectly well.
However, things start to become ugly if the function uses local variables
and the caller passes a variable name that collides with one of them.
A demonstration, using the printf variant:
hobbit:~$ f() { local a=computed_output; printf -v "$1" "$a"; }
hobbit:~$ unset -v x; f x; declare -p x
declare -- x="computed_output"
hobbit:~$ unset -v a; f a; declare -p a
bash: declare: a: not found
When $1 is "a", the output value is written to the variable named "a",
which is the function's local variable.
There is unfortunately *no* way at all to define a local reference to
a variable in a different scope. You're at the mercy of bash's
dynamic scoping rules.
The only workaround for that is to make all of your local variables
obscure, so that the caller is unlikely to duplicate them. Prefixing
every local variable with something like _myfunc_ (underscore,
function name, underscore) is one way to ensure a lack of collisions,
as long as the caller doesn't go out of their way to cause breakage.
Obviously, this makes the code uglier.
Reply to: