Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: unexpected unmodified variable

On Fri, Oct 7, 2022 at 8:28 AM Ray Andrews <rayandrews@xxxxxxxxxxx> wrote:
> By default the function is implemented by a shell function of the same name; if
> shellfn  is specified it gives the name of the corresponding shell function
> while mathfn remains the name used in  arithmetical  expressions.

As with widgets, you can have a math function named X that's
implemented by a shell function named Y.  The default is that if the
shell function is Y, then the math function is also Y.

> The name
> of  the  function in $0 is mathfn (not shellfn as would usually be the case),
> provided the option FUNCTION_ARGZERO is in  effect.

This is just explaining how $0 works in case you're trying to have a
function that references itself by name.

> The  positional
> parameters  in  the shell function correspond to the arguments of the mathe‐
> matical function call.

If you write $(( func2(a,b,c) )) then inside func2, $1 == a, $2 == b, $3 == c

"Positional parameters" always means $1, $2, etc., that's not
math-function-specific, it's just shell terminology.

> The result of the last arithmetical expression eval‐
> uated inside the shell function (even if it is a form that normally only re‐
> turns a status) gives the result of the mathematical function.

The parenthetical refers to the fact that some math operations are
true/false, e.g. (( x > 12)) "is a form that only returns a status".
Omitting that, the rest of the sentence should be clear.

> ... which might just be the most impenetrable bit of computer bafflegab I've ever read, I can't get past the first sentence.

Seriously?  This is all using phrases that refer to concepts appearing
elsewhere throughout the zsh manual.

> You have to be Peter to understand that.

Well, he did write it.

> No typo, everything is copied and pasted without edit:

Oh.  Given the way you wrote func2, if you remove the return statement
there are NO math expressions in func2 at all, so $(( func2() )) is
[except for side-effects] a no-op, and the assignment in var=$((
func2() )) is just skipped, leaving the previous value of $var
unchanged.  If you turn the count=2 assignment into a math expression,
either by your "integer count=2" test or by using (( count=2 )), then
$(( func2() )) returns the value from that.

It is a bit weird that var=$((...)) does nothing at all in that
circumstance, I would have expected it either to assign empty string
to $var or to have a nonzero $? as a result.  Unanticipated edge case,
possible bug.

> Tho I do wonder why '$(( ))' is 'local' and '$( )' spawns a subshell

$(...) spawns a subshell because stdin/stdout text is passed from one
process to another using pipes, and if a process has a pipe to itself
it can deadlock trying to read something it hasn't written yet (or
write something there isn't room for because not enough has been read

$((...)) looks that way by analogy to ((...)), not by analogy to $(...).

> one might wish for some method of asking '$( )' to run 'local' too

"Local" text substitution is what ordinary $param references are for
... $(...) specifically means to use processes and pipes.  That said,
a still-missing feature in zsh is the ability to tie a function to a
variable so that referencing the variable as $foo invokes the function
that's tied to it, to produce the effect you're asking for.  Ksh has a
syntax for that.

Messages sorted by: Reverse Date, Date, Thread, Author