From: Daniel Shahaf <d.s@daniel.shahaf.name>
To: zsh-workers@zsh.org
Subject: Re: zmathfunc: min, max, sum throw error if result equals 0
Date: Fri, 16 Apr 2021 19:50:28 +0000 [thread overview]
Message-ID: <20210416195028.GE15670@tarpaulin.shahaf.local2> (raw)
In-Reply-To: <CAH+w=7ZFbOJc16r6JX4Lr6uPdVRji_=RmY3WZVBK9GtXzxjPmA@mail.gmail.com>
Again sorry for the delay on getting back to this.
Bart Schaefer wrote on Sun, Mar 07, 2021 at 18:25:00 -0800:
> On Sun, Mar 7, 2021 at 1:57 PM Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
> >
> > Bart Schaefer wrote on Sun, 07 Mar 2021 21:39 +00:00:
> >
> > > Is it worth testing invalid cases? Such as uses outside math context
> > > where the arguments are not syntax checked?
> >
> > If you have ideas, feel free to write them and post them; I'll
> > transplant them into Z02 once I have committed it.
>
> One possibility below; I'll follow up if I think of more.
>
> With your patch adding "true" at the end, we get this:
>
> % zsh_math_func_min "foo bar" x y z
> zsh_math_func_min:7: bad math expression: operator expected at `bar'
> zsh_math_func_min:7: bad math expression: operator expected at `bar'
> zsh_math_func_min:7: bad math expression: operator expected at `bar'
> zsh_math_func_min:9: bad math expression: operator expected at `bar'
> toltec-ubuntu% echo $?
> 0
>
> Doesn't seem as though anything that prints that many error messages
> should return zero.
>
Patch below.
> > > Because of the way math context works, if any of $@ is a string that
> > > can be interpreted as a math expression, the above will evaluate it at
> > > least twice (and up to $# times in the case of $1). This could have
> > > side-effects.
> >
> > Could you post a regression test for this?
>
> In thinking more about it, I believe this only matters when the
> function is called outside of math context. In math context, the
> arguments are all going to be evaluated down to numbers before they
> are passed to the function.
>
> % (( x = 0 )); zsh_math_func_min "x += 2" 4 5 6
> % print $x
> 8
> % (( (x = 0), min("x += 2", 4, 5, 6) ))
> % print $x
> 2
I see. Still, going to fix this, if only because those min() max()
sum() implementations are virtually the only example of `functions -M`
in the tree, and it'd be good to have a complete example.
> > Related to code as it is in master, are «(( $arg < result ))» and
> > «(( arg < result ))» equivalent?
>
> No, but again math context matters.
>
> % arg="x += 2" x=0 result=0
> % (( $arg > result )) && result=$arg
> % print $result $x $(( result )) $x
> x += 2 1 3 3
> % x=0 result=0
> % (( arg > result )) && (( result=arg ))
> % print $result $x $(( result )) $x
> 4 4 4 4
Nice. So the first one interpolates $arg as in double-quoted strings
and then parses the string " x += 2 > result ", where the > operator has
higher precedence, and «2 > result» evaluates to 1, and the «print» then
evaluates everything left to right; whereas the latter sees «arg» and
tries to evaluate that _as a number_, which works out to 2 (with a side
effect), so the condition evaluates to true, and the assignment on the
RHS then works out to 4 (with a side effect). Clear as a cloudless day ☺
Many thanks.
Daniel
diff --git a/Functions/Math/zmathfunc b/Functions/Math/zmathfunc
index 8e4b78549..28f21e562 100644
--- a/Functions/Math/zmathfunc
+++ b/Functions/Math/zmathfunc
@@ -6,7 +6,12 @@ zsh_math_func_min() {
shift
local arg
for arg ; do
- (( $arg < result )) && result=$arg
+ (( $arg < result ))
+ case $? in
+ (0) result=$arg;;
+ (1) ;;
+ (*) return $?;;
+ esac
done
(( result ))
true # Careful here: `return 0` evaluates an arithmetic expression
@@ -19,7 +24,12 @@ zsh_math_func_max() {
shift
local arg
for arg ; do
- (( $arg > result )) && result=$arg
+ (( $arg > result ))
+ case $? in
+ (0) result=$arg;;
+ (1) ;;
+ (*) return $?;;
+ esac
done
(( result ))
true # Careful here: `return 0` evaluates an arithmetic expression
@@ -31,7 +41,7 @@ zsh_math_func_sum() {
local sum
local arg
for arg ; do
- (( sum += $arg ))
+ (( sum += arg ))
done
(( sum ))
true # Careful here: `return 0` evaluates an arithmetic expression
next prev parent reply other threads:[~2021-04-16 19:50 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-07 16:37 Nikolaus Thiel
2021-03-07 17:17 ` Daniel Shahaf
2021-03-07 21:39 ` Bart Schaefer
2021-03-07 21:56 ` Daniel Shahaf
2021-03-08 2:25 ` Bart Schaefer
2021-04-16 18:26 ` Daniel Shahaf
2021-04-16 18:47 ` Bart Schaefer
2021-04-16 19:50 ` Daniel Shahaf [this message]
2021-04-16 20:05 ` Bart Schaefer
2021-04-16 20:08 ` Daniel Shahaf
2021-04-16 18:21 ` Daniel Shahaf
2021-05-16 14:54 ` Lawrence Velázquez
2021-05-18 2:02 ` Daniel Shahaf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210416195028.GE15670@tarpaulin.shahaf.local2 \
--to=d.s@daniel.shahaf.name \
--cc=zsh-workers@zsh.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).