zsh-users
 help / color / mirror / code / Atom feed
* A bug or improperly formatted script
@ 2017-02-25 18:34 Jim
  2017-02-25 22:12 ` Bart Schaefer
  0 siblings, 1 reply; 5+ messages in thread
From: Jim @ 2017-02-25 18:34 UTC (permalink / raw)
  To: zsh-users

[-- Attachment #1: Type: text/plain, Size: 1137 bytes --]

ZSH_VERSION:  4.3.17, 5.0.8, 5.2, 5,3.1

While doing a search, unrelated, I found the following on the
zsh-lovers(1) man page:

# Count the number of directories on the stack
  $ print $((${${(z)${(f)"$(dirs -v)"}[-1]}[1]} + 1)) #...

I was surprised the first time I tried it I got "-2" as the output.

Modifying the script to

$ print $((${(z)${(fO)"$(dirs -v)"}[1][1]} + 1))

returned "1" as expected.  "dirs -v" outputs "0      ~".  Stripping the

expression from the original script, outputs, "~" whereas the modified

script returns "0".  It would appear as if the original script is returning

a scalar when the stack only has one entry and an array when the

stack has 2 or more entries.  Tested another, somewhat unrealistic,

case with a directory "-" under the home directory "0      ~/-", the

output was "-1" for the original script.

So, is this a bug, or scripting?  Hard to believe someone

hadn't run across something like this before.


Sincerely,

Jim

Sorry if this email looks strange, gmail, as least while composing,

looked really strange after a cut/paste dropped in some fixed font

and line spacing went nuts.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: A bug or improperly formatted script
  2017-02-25 18:34 A bug or improperly formatted script Jim
@ 2017-02-25 22:12 ` Bart Schaefer
  2017-02-25 22:53   ` Jim
  0 siblings, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2017-02-25 22:12 UTC (permalink / raw)
  To: linuxtechguy, zsh-users

On Feb 25, 12:34pm, Jim wrote:
}
} While doing a search, unrelated, I found the following on the
} zsh-lovers(1) man page:
} 
} # Count the number of directories on the stack
}   $ print $((${${(z)${(f)"$(dirs -v)"}[-1]}[1]} + 1)) #...
} 
} I was surprised the first time I tried it I got "-2" as the output.
} 
} It would appear as if the original script is returning
} a scalar when the stack only has one entry and an array when the
} stack has 2 or more entries.

Yes, this is a known / traditional behavior, and it somewhat regularly
comes up in examples where a program has been tested only in the "more
than one element" cases.

The problem is that nesting ${${...}} "wants" to treat the inner ${...}
as a scalar, and will do so unless something else forces it to be an
array.  (f) doesn't accomplish that because $(dirs -v) produces only
one line of output with the final newline stripped, so there is nothing
for (f) to split on.  (@) won't accomplish it because it only means
that things that are already arrays should remain so.

So what can be done to force interpretation as an array here?  Unless
someone else has a better solution, the answer is to forcibly assign
the result to an array variable:

print $((${${(z)${(Af)reply::="$(dirs -v)"}[-1]}[1]} + 1))

Once we are expanding ${reply} rather than ${"$(dirs -v")} the array
property is preserved and [-1] remains an array subscript instead of
becoming a scalar string slice.

A follow-up to this is going to zsh-workers.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: A bug or improperly formatted script
  2017-02-25 22:12 ` Bart Schaefer
@ 2017-02-25 22:53   ` Jim
  2017-02-25 23:41     ` Bart Schaefer
  0 siblings, 1 reply; 5+ messages in thread
From: Jim @ 2017-02-25 22:53 UTC (permalink / raw)
  To: zsh-users

[-- Attachment #1: Type: text/plain, Size: 1546 bytes --]

On Sat, Feb 25, 2017 at 4:12 PM, Bart Schaefer <schaefer@brasslantern.com>
wrote:

> Yes, this is a known / traditional behavior, and it somewhat regularly
> comes up in examples where a program has been tested only in the "more
> than one element" cases.
>
> The problem is that nesting ${${...}} "wants" to treat the inner ${...}
> as a scalar, and will do so unless something else forces it to be an
> array.  (f) doesn't accomplish that because $(dirs -v) produces only
> one line of output with the final newline stripped, so there is nothing
> for (f) to split on.  (@) won't accomplish it because it only means
> that things that are already arrays should remain so.
>
> So what can be done to force interpretation as an array here?  Unless
> someone else has a better solution, the answer is to forcibly assign
> the result to an array variable:
>
> print $((${${(z)${(Af)reply::="$(dirs -v)"}[-1]}[1]} + 1))
>

Good to know.  So in my original email the alternate example

 print $((${(z)${(fO)"$(dirs -v)"}[1][1]} + 1))

was this forcing it to an array or was it a fluke?  I assumed(bad
thing to do) that it had and "[1][1]" would then work properly.  It does
return the desired results for a single or multiple line output from
"dirs -v".


> Once we are expanding ${reply} rather than ${"$(dirs -v")} the array
> property is preserved and [-1] remains an array subscript instead of
> becoming a scalar string slice.
>
> A follow-up to this is going to zsh-workers.
>

I will forward this on to zsh-lovers.

Thanks for your help.

Jim

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: A bug or improperly formatted script
  2017-02-25 22:53   ` Jim
@ 2017-02-25 23:41     ` Bart Schaefer
  2017-02-26  0:58       ` Jim
  0 siblings, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2017-02-25 23:41 UTC (permalink / raw)
  To: linuxtechguy, zsh-users

On Feb 25,  4:53pm, Jim wrote:
}
} So in my original email the alternate example
} 
}  print $((${(z)${(fO)"$(dirs -v)"}[1][1]} + 1))
} 
} was this forcing it to an array or was it a fluke?

It was a fluke.  ${${$(print $'0\t~')[1]}[1]} == '0' whereas
${${$(print $'0\t~')[-1]}[1]} == '~' and $(( ~ + 1 )) == -2 (the
tilde being interpreted as bitwise negation).

Double-subscripting $var[1][1] yields the same byte whether $var is
a scalar or an array, whereas $var[-1][1] does not unless the scalar
is only a single character to begin with.

You'd never have seen -2 if $HOME were not the only entry in the
stack.  With $(dirs -lv) or with most other directories, the last char
of the directory name would have been intepreted as a variable name
and potentially produced even stranger results (though most like it
would be an unset variable and thus be treated as zero, hiding the
effect entirely).  A directory name ending in digits would have made
things even stranger.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: A bug or improperly formatted script
  2017-02-25 23:41     ` Bart Schaefer
@ 2017-02-26  0:58       ` Jim
  0 siblings, 0 replies; 5+ messages in thread
From: Jim @ 2017-02-26  0:58 UTC (permalink / raw)
  To: zsh-users

[-- Attachment #1: Type: text/plain, Size: 1390 bytes --]

On Sat, Feb 25, 2017 at 5:41 PM, Bart Schaefer <schaefer@brasslantern.com>
wrote:

> On Feb 25,  4:53pm, Jim wrote:
> }
> } So in my original email the alternate example
> }
> }  print $((${(z)${(fO)"$(dirs -v)"}[1][1]} + 1))
> }
> } was this forcing it to an array or was it a fluke?
>
> It was a fluke.  ${${$(print $'0\t~')[1]}[1]} == '0' whereas
> ${${$(print $'0\t~')[-1]}[1]} == '~' and $(( ~ + 1 )) == -2 (the
> tilde being interpreted as bitwise negation).
>
> Double-subscripting $var[1][1] yields the same byte whether $var is
> a scalar or an array, whereas $var[-1][1] does not unless the scalar
> is only a single character to begin with.
>
> You'd never have seen -2 if $HOME were not the only entry in the
> stack.  With $(dirs -lv) or with most other directories, the last char
> of the directory name would have been intepreted as a variable name
> and potentially produced even stranger results (though most like it
> would be an unset variable and thus be treated as zero, hiding the
> effect entirely).  A directory name ending in digits would have made
> things even stranger.
>

Still digesting, but I can say I learned my something new for today, so
the day wasn't wasted.  Looking forward to the patch you submitted.
I had tried the (A) flag, just in case it might work, but it didn't.
Wondered myself why it shouldn't apply in the case.

Thanks for your help.

Jim

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-02-26  0:58 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-25 18:34 A bug or improperly formatted script Jim
2017-02-25 22:12 ` Bart Schaefer
2017-02-25 22:53   ` Jim
2017-02-25 23:41     ` Bart Schaefer
2017-02-26  0:58       ` Jim

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).