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

Re: unexpected unmodified variable




On 2022-10-06 21:36, Bart Schaefer wrote:
Yes, that's documented. Interpreting the argument of "return" counts
as a math operation, so the math value of a "functions -M" function
really is always the last math operation.

Bart, can you point me to something where I can read up on this 'functions -M', I was just using it on faith and because things broke without it.  I've never used that before and never seemed to miss it.  In the manual I read:

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 func‐ tion
while mathfn remains the name used in  arithmetical  expressions.   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.   The  positional
parameters  in  the shell function correspond to the arguments of the mathe‐
matical function call.  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.

... which might just be the most impenetrable bit of computer bafflegab I've ever read, I can't get past the first sentence.  You have to be Peter to understand that.


I think you must have typo'd something somewhere.  Add "functions -t
func2" so you can see a trace of what's executing.

No typo, everything is copied and pasted without edit:

The file 'test1':

#!/usr/bin/zsh

functions -M func2
func2 ()
{
functions -t func2
echo func2 here!
count=2
#return 3
}
func1 ()
{
functions -t func2
local count=1

var=$(( func2() ))

# Count = 1, no effect:
#var=$( func2 )

echo var is: $var, count is $count
}


The run:

0 /aWorking/Zsh/Source/Wk 3 $ . test1; func1
+func2:2:>functions -t func2
+func2:3:>echo func2 'here!'
func2 here!
+func2:4:>count=2
var is: 0, count is 2                          <<< With 'return 3' commented out.

0 /aWorking/Zsh/Source/Wk 3 $ . test1; func1
+func2:2:>functions -t func2
+func2:3:>echo func2 'here!'
func2 here!
+func2:4:>count=2
+func2:5:>return 3
var is: 3, count is 2                         <<< With 'return 3' active.

0 /aWorking/Zsh/Source/Wk 3 $ . test1; func1
+func2:2:>functions -t func2
+func2:3:>echo func2 'here!'
func2 here!
+func2:4:>count=2
var is: 3, count is 2                        <<< With 'return 3' commented out again.

this case, doesn't matter.  What matters is that $(( func2() )) runs
in the current shell, not in a subshell.

Right, I understand that.  So long as there's math involved, there's no subshell.

BTW, if I modify func2:

func2 ()
{
functions -t func2
echo func2 here!
#integer count=2
#return 3
}

... the same pattern results:

'# integer count=2':  and count is unchanged in func1, var = 0.

'integer count=2':  and count is unchanged in func1 but var = 2.  I force it to be a math op.  The 'integer count' seems to be a new variable so the original is unchanged, that's clear. 

'# integer count=2':  and var is '2'.  func2 retains the previous return value even thou the active line is commented out (again).  Unless I'm making some kind of mistake, it seems buggy to me, the rv of func2 is floating unchanged somewhere.  When I explicitly change it, it changes, but then the new value floats there too.  I've done it a dozen times, I don't think I'm wrong.  I have to start a new shell to erase that rv.  Or is this some bizarre local issue here?

Tho I do wonder why '$(( ))' is 'local' and '$( )' spawns a subshell, dunno, maybe there's a good reason for that but one might wish for some method of asking '$( )' to run 'local' too, so that my original issue wouldn't come up.  I appreciate that this kind of thing is so deep in the way the shell runs that it might be next to impossible even if anyone but me was interested in it.  Still: "setopt NO_SUBSHELL" might be very useful. 


 



In case it wasn't obvious, $(( func2 )) treats func2 as the name of a
variable, not a function, so it doesn't run func2 at all.

Yes, that's clear.  '$(( func2() ))' is a math operation -- grab the return value, which is whatever the last math operation was.  '$(( func2 ))' is ... basically nothing.





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