help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Local variables for nested function calls


From: Greg Wooledge
Subject: Re: Local variables for nested function calls
Date: Wed, 28 Jul 2021 14:59:22 -0400

On Wed, Jul 28, 2021 at 08:46:56PM +0200, eduardo-chibas@caramail.com wrote:
> The problem started with a function `plist` that calls another function 
> `region`.
> 
> ----- function plist -----
> 
> ropts=("$@")
> 
> # read function arguments here
> "-d")
>   local -r dpath="$2" ; shift 2 ;;
> 
> local fdir=${dpath:-$PWD}
> 
> region "${ropts[@]}"
> 
> ----- plist ends here -----

You have ropts as non-local variable here, FYI.  That may or may not
be what you want.

> ----- function region -----
> 
> # read function arguments here
>  "-d")
>     local fdir=$2 ; shift 2 ;;
> 
> : "${fdir:="${@:$#}"}"}
> 
> ----- region ends here -----

> When I was calling `plist` without the -d option, and subsequently calling
> `region`, the value of `fdir` was being set to `$PWD`, rather than the last
> argument passed to `region`.

If you don't include the -d option, then you're skipping over the
"local fdir" in the second function, which means it's going to use dynamic
scope to find the fdir variable in the first function.

> This means that I have to declare my variables local without setting them
> first.

Well, yeah.  If region is supposed to have its own local fdir which is
independent of the one in plist, then you should declare fdir in region.
And not only when the -d option is given.

As a general programming principle, you've got a block of code which
has a local variable defined inside it, which is great.  But then
you're using the variable after that block of code has terminated.
That's *not* great.  In some languages, that would be an error (the
compiler or interpreter would yell at you).  In bash, it's not an error;
you have to catch it yourself.

If fdir is supposed to be local throughout the entire function, then I'd
declare it at the *top* of the function.  Or as close to the top as you
can reasonably make it.

> But then I see no point of using parameter expansion such as `: 
> "${fdir:="${@:$#}"}"}`
> to set defaults because `fdir` would already be defined when I use the local 
> declaration
> within `region`.

... I still don't know what you're trying to *do*, though.

I don't know what "fdir" even stands for, or why you're setting it, or
why you're setting it a second time, or how you use it.

That makes it hard to give advice beyond generalities.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]