Skip to content

Commit

Permalink
users/29882: Explain $RANDOM predictability
Browse files Browse the repository at this point in the history
  • Loading branch information
bartschaefer committed May 25, 2024
1 parent 300ce96 commit 9dcaf78
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
2 changes: 2 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
2024-05-24 Bart Schaefer <[email protected]>

* users/29882: Etc/FAQ.yo: Explain $RANDOM predictability

* 52910: Functions/Misc/zmv: Improve handling of **/ patterns

* 52904: Completion/Unix/Command/_git: Improve quoting of paths
Expand Down
32 changes: 32 additions & 0 deletions Etc/FAQ.yo
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ Chapter 3: How to get various things to work
3.28. How do I edit the input buffer in $EDITOR?
3.29. Why does `which' output for missing commands go to stdout?
3.30. Why doesn't the expansion mytt(*.{tex,aux,pdf}) do what I expect?
3.31. Why does mytt($RANDOM) return the same number more than once?

Chapter 4: The mysteries of completion
4.1. What is completion?
Expand Down Expand Up @@ -2219,6 +2220,37 @@ sect(Why doesn't the expansion mytt(*.{tex,aux,pdf}) do what I expect?)
This is harder for the user to remember but easier for the shell to
parse!

sect(Why does mytt($RANDOM) return the same number more than once?)

As tt(zshparam(1)) says:
verb(
The values of RANDOM form an intentionally-repeatable
pseudo-random sequence; subshells that reference RANDOM
will result in identical pseudo-random values unless the
value of RANDOM is referenced or seeded in the parent shell
in between subshell invocations.
)

You can use a function, including an anonymous function, to always
evaluate mytt($RANDOM) in the parent shell. This example illustrates
the difference:
verb(
for i in {1..10}; do
echo subshell: $(echo $RANDOM) $RANDOM
() { echo parent: $(echo $1) $2 } $RANDOM $RANDOM;
done
)

Remember that for a pipe like mytt(A | B), zsh runs A in a subshell
and B in the current shell. This means that, for example:
verb(
for i in {1..10}; do
echo $RANDOM | tee
done
)
also repeats the same value, because mytt($RANDOM) is evaluated in
the subshell and the parent sequence is left unchanged.

chapter(The mysteries of completion)

sect(What is completion?)
Expand Down

0 comments on commit 9dcaf78

Please sign in to comment.