mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-05 03:17:50 +08:00
Revise doc for the builtin module.
- Revise the introduction section. - Link to the notes on commands taking value inputs from all such commands. - Revise the doc on the "all" command. - Revise references to the builtin module from the language reference.
This commit is contained in:
parent
44e300095b
commit
7da4b58f2f
|
@ -66,9 +66,9 @@ func nsFn(m vals.Map) (*Ns, error) {
|
|||
// make-map $input?
|
||||
// ```
|
||||
//
|
||||
// Outputs a map from an input consisting of containers with two elements. The
|
||||
// first element of each container is used as the key, and the second element is
|
||||
// used as the value.
|
||||
// Outputs a map from the [value inputs](#value-inputs), each of which must be
|
||||
// an iterable value with with two elements. The first element of each value
|
||||
// is used as the key, and the second element is used as the value.
|
||||
//
|
||||
// If the same key appears multiple times, the last value is used.
|
||||
//
|
||||
|
|
|
@ -94,10 +94,10 @@ func runParallel(fm *Frame, functions ...Callable) error {
|
|||
//elvdoc:fn each
|
||||
//
|
||||
// ```elvish
|
||||
// each $f $input-list?
|
||||
// each $f $inputs?
|
||||
// ```
|
||||
//
|
||||
// Call `$f` on all inputs.
|
||||
// Calls `$f` on each [value input](#value-inputs).
|
||||
//
|
||||
// An exception raised from [`break`](#break) is caught by `each`, and will
|
||||
// cause it to terminate early.
|
||||
|
@ -152,14 +152,14 @@ func each(fm *Frame, f Callable, inputs Inputs) error {
|
|||
//elvdoc:fn peach
|
||||
//
|
||||
// ```elvish
|
||||
// peach $f $input-list?
|
||||
// peach $f $inputs?
|
||||
// ```
|
||||
//
|
||||
// Calls `$f` on all inputs, possibly in parallel.
|
||||
// Calls `$f` for each [value input](#value-inputs), possibly in parallel.
|
||||
//
|
||||
// Like `each`, an exception raised from [`break`](#break) will cause `peach`
|
||||
// to terminate early. However due to the parallel nature of `peach`, the exact
|
||||
// time of termination is non-deterministic and not even guaranteed.
|
||||
// time of termination is non-deterministic, and termination is not guaranteed.
|
||||
//
|
||||
// An exception raised from [`continue`](#continue) is swallowed and can be used
|
||||
// to terminate a single iteration early.
|
||||
|
|
|
@ -824,11 +824,11 @@ func fromTerminated(fm *Frame, terminator string) error {
|
|||
//elvdoc:fn to-lines
|
||||
//
|
||||
// ```elvish
|
||||
// to-lines $input?
|
||||
// to-lines $inputs?
|
||||
// ```
|
||||
//
|
||||
// Writes each value input to a separate line in the byte output. Byte input is
|
||||
// ignored.
|
||||
// Writes each [value input](#value-inputs) to a separate line in the byte
|
||||
// output. Byte input is ignored.
|
||||
//
|
||||
// ```elvish-transcript
|
||||
// ~> put a b | to-lines
|
||||
|
@ -861,12 +861,14 @@ func toLines(fm *Frame, inputs Inputs) error {
|
|||
//elvdoc:fn to-terminated
|
||||
//
|
||||
// ```elvish
|
||||
// to-terminated $terminator $input?
|
||||
// to-terminated $terminator $inputs?
|
||||
// ```
|
||||
//
|
||||
// Writes each value input to the byte output with the specified terminator character. Byte input is
|
||||
// ignored. This behavior is useful, for example, when feeding output into a program that accepts
|
||||
// NUL terminated lines to avoid ambiguities if the values contains newline characters.
|
||||
// Writes each [value input](#value-inputs) to the byte output with the
|
||||
// specified terminator character. Byte input is ignored. This behavior is
|
||||
// useful, for example, when feeding output into a program that accepts NUL
|
||||
// terminated lines to avoid ambiguities if the values contains newline
|
||||
// characters.
|
||||
//
|
||||
// The `$terminator` must be a single ASCII character such as `"\x00"` (NUL).
|
||||
//
|
||||
|
|
|
@ -151,13 +151,13 @@ var eawkWordSep = regexp.MustCompile("[ \t]+")
|
|||
//elvdoc:fn eawk
|
||||
//
|
||||
// ```elvish
|
||||
// eawk $f $input-list?
|
||||
// eawk $f $inputs?
|
||||
// ```
|
||||
//
|
||||
// For each input, call `$f` with the input followed by all its fields. A
|
||||
// [`break`](./builtin.html#break) command will cause `eawk` to stop processing
|
||||
// inputs. A [`continue`](./builtin.html#continue) command will exit $f, but is
|
||||
// ignored by `eawk`.
|
||||
// For each [value input](#value-inputs), calls `$f` with the input followed by
|
||||
// all its fields. A [`break`](./builtin.html#break) command will cause `eawk`
|
||||
// to stop processing inputs. A [`continue`](./builtin.html#continue) command
|
||||
// will exit $f, but is ignored by `eawk`.
|
||||
//
|
||||
// It should behave the same as the following functions:
|
||||
//
|
||||
|
|
|
@ -27,38 +27,82 @@ func init() {
|
|||
//elvdoc:fn all
|
||||
//
|
||||
// ```elvish
|
||||
// all $input-list?
|
||||
// all $inputs?
|
||||
// ```
|
||||
//
|
||||
// Passes inputs to the output as is. Byte inputs into values, one per line.
|
||||
// Takes [value inputs](#value-inputs), and outputs those values unchanged.
|
||||
//
|
||||
// This is an identity function for commands with value outputs: `a | all` is
|
||||
// equivalent to `a` if it only outputs values.
|
||||
// This is an [identity
|
||||
// function](https://en.wikipedia.org/wiki/Identity_function) for the value
|
||||
// channel; in other words, `a | all` is equivalent to just `a` if `a` only has
|
||||
// value output.
|
||||
//
|
||||
// This function is useful for turning inputs into arguments, like:
|
||||
// This command can be used inside output capture (i.e. `(all)`) to turn value
|
||||
// inputs into arguments. For example:
|
||||
//
|
||||
// ```elvish-transcript
|
||||
// ~> use str
|
||||
// ~> put 'lorem,ipsum' | str:split , (all)
|
||||
// ▶ lorem
|
||||
// ▶ ipsum
|
||||
// ```
|
||||
//
|
||||
// Or capturing all inputs in a variable:
|
||||
//
|
||||
// ```elvish-transcript
|
||||
// ~> x = [(all)]
|
||||
// foo
|
||||
// bar
|
||||
// (Press ^D)
|
||||
// ~> put $x
|
||||
// ~> echo '["foo","bar"] ["lorem","ipsum"]' | from-json
|
||||
// ▶ [foo bar]
|
||||
// ▶ [lorem ipsum]
|
||||
// ~> echo '["foo","bar"] ["lorem","ipsum"]' | from-json | put (all)[0]
|
||||
// ▶ foo
|
||||
// ▶ lorem
|
||||
// ```
|
||||
//
|
||||
// When given a list, it outputs all elements of the list:
|
||||
// The latter pipeline is equivalent to the following:
|
||||
//
|
||||
// ```elvish-transcript
|
||||
// ~> all [foo bar]
|
||||
// ~> put (echo '["foo","bar"] ["lorem","ipsum"]' | from-json)[0]
|
||||
// ▶ foo
|
||||
// ▶ lorem
|
||||
// ```
|
||||
//
|
||||
// In general, when `(all)` appears in the last command of a pipeline, it is
|
||||
// equivalent to just moving the previous commands of the pipeline into `()`.
|
||||
// The choice is a stylistic one; the `(all)` variant is longer overall, but can
|
||||
// be more readable since it allows you to avoid putting an excessively long
|
||||
// pipeline inside an output capture, and keeps the data flow within the
|
||||
// pipeline.
|
||||
//
|
||||
// Putting the value capture inside `[]` (i.e. `[(all)]`) is useful for storing
|
||||
// all value inputs in a list for further processing:
|
||||
//
|
||||
// ```elvish-transcript
|
||||
// ~> fn f { var inputs = [(all)]; put $inputs[1] }
|
||||
// ~> put foo bar baz | f
|
||||
// ▶ bar
|
||||
// ```
|
||||
//
|
||||
// The `all` command can also take "inputs" from an iterable argument. This can
|
||||
// be used to flatten lists or strings (although not recursively):
|
||||
//
|
||||
// ```elvish-transcript
|
||||
// ~> all [foo [lorem ipsum]]
|
||||
// ▶ foo
|
||||
// ▶ [lorem ipsum]
|
||||
// ~> all foo
|
||||
// ▶ f
|
||||
// ▶ o
|
||||
// ▶ o
|
||||
// ```
|
||||
//
|
||||
// This can be used together with `(one)` to turn a single iterable value in the
|
||||
// pipeline into its elements:
|
||||
//
|
||||
// ```elvish-transcript
|
||||
// ~> echo '["foo","bar","lorem"]' | from-json
|
||||
// ▶ [foo bar lorem]
|
||||
// ~> echo '["foo","bar","lorem"]' | from-json | all (one)
|
||||
// ▶ foo
|
||||
// ▶ bar
|
||||
// ▶ lorem
|
||||
// ```
|
||||
//
|
||||
// When given byte inputs, the `all` command currently functions like
|
||||
// [`from-lines`](#from-lines), although this behavior is subject to change:
|
||||
//
|
||||
// ```elvish-transcript
|
||||
// ~> print "foo\nbar\n" | all
|
||||
// ▶ foo
|
||||
// ▶ bar
|
||||
// ```
|
||||
|
@ -80,14 +124,14 @@ func all(fm *Frame, inputs Inputs) error {
|
|||
//elvdoc:fn one
|
||||
//
|
||||
// ```elvish
|
||||
// one $input-list?
|
||||
// one $inputs?
|
||||
// ```
|
||||
//
|
||||
// Passes inputs to outputs, if there is only a single one. Otherwise raises an
|
||||
// exception.
|
||||
// Takes exactly one [value input](#value-inputs) and outputs it. If there are
|
||||
// more than one value inputs, raises an exception.
|
||||
//
|
||||
// This function can be used in a similar way to [`all`](#all), but is a better
|
||||
// choice when you expect that there is exactly one output:
|
||||
// choice when you expect that there is exactly one output.
|
||||
//
|
||||
// @cf all
|
||||
|
||||
|
@ -109,13 +153,18 @@ func one(fm *Frame, inputs Inputs) error {
|
|||
//elvdoc:fn take
|
||||
//
|
||||
// ```elvish
|
||||
// take $n $input-list?
|
||||
// take $n $inputs?
|
||||
// ```
|
||||
//
|
||||
// Retain the first `$n` input elements. If `$n` is larger than the number of input
|
||||
// elements, the entire input is retained. Examples:
|
||||
// Outputs the first `$n` [value inputs](#value-inputs). If `$n` is larger than
|
||||
// the number of value inputs, outputs everything.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// ```elvish-transcript
|
||||
// ~> range 2 | take 10
|
||||
// ▶ 0
|
||||
// ▶ 1
|
||||
// ~> take 3 [a b c d e]
|
||||
// ▶ a
|
||||
// ▶ b
|
||||
|
@ -123,9 +172,6 @@ func one(fm *Frame, inputs Inputs) error {
|
|||
// ~> use str
|
||||
// ~> str:split ' ' 'how are you?' | take 1
|
||||
// ▶ how
|
||||
// ~> range 2 | take 10
|
||||
// ▶ 0
|
||||
// ▶ 1
|
||||
// ```
|
||||
//
|
||||
// Etymology: Haskell.
|
||||
|
@ -151,15 +197,19 @@ func take(fm *Frame, n int, inputs Inputs) error {
|
|||
//elvdoc:fn drop
|
||||
//
|
||||
// ```elvish
|
||||
// drop $n $input-list?
|
||||
// drop $n $inputs?
|
||||
// ```
|
||||
//
|
||||
// Drop the first `$n` elements of the input. If `$n` is larger than the number of
|
||||
// input elements, the entire input is dropped.
|
||||
// Ignores the first `$n` [value inputs](#value-inputs) and outputs the rest.
|
||||
// If `$n` is larger than the number of value inputs, outputs nothing.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// ```elvish-transcript
|
||||
// ~> range 10 | drop 8
|
||||
// ▶ (num 8)
|
||||
// ▶ (num 9)
|
||||
// ~> range 2 | drop 10
|
||||
// ~> drop 2 [a b c d e]
|
||||
// ▶ c
|
||||
// ▶ d
|
||||
|
@ -168,7 +218,6 @@ func take(fm *Frame, n int, inputs Inputs) error {
|
|||
// ~> str:split ' ' 'how are you?' | drop 1
|
||||
// ▶ are
|
||||
// ▶ 'you?'
|
||||
// ~> range 2 | drop 10
|
||||
// ```
|
||||
//
|
||||
// Etymology: Haskell.
|
||||
|
@ -251,8 +300,9 @@ func count(fm *Frame, args ...interface{}) (int, error) {
|
|||
// order &reverse=$false $less-than=$nil $inputs?
|
||||
// ```
|
||||
//
|
||||
// Outputs the input values sorted in ascending order. The sort is guaranteed to
|
||||
// be [stable](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability).
|
||||
// Outputs the [value inputs](#value-inputs) sorted
|
||||
// in ascending order. The sorting process is guaranteed to be
|
||||
// [stable](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability).
|
||||
//
|
||||
// The `&reverse` option, if true, reverses the order of output.
|
||||
//
|
||||
|
|
|
@ -8,13 +8,20 @@ The builtin module contains facilities that are potentially useful to all users.
|
|||
|
||||
## Using builtin: explicitly
|
||||
|
||||
The builtin module is consulted implicitly when resolving unqualified names, so
|
||||
you usually don't need to specify `builtin:` explicitly. However, there are some
|
||||
cases where it is useful to do that:
|
||||
The builtin module is consulted implicitly when
|
||||
[resolving unqualified names](language.html#scoping-rule), and Elvish's
|
||||
namespacing mechanism makes it impossible for other modules to redefine builtin
|
||||
symbols. It's almost always sufficient (and safe) to use builtin functions and
|
||||
variables with their unqualified names.
|
||||
|
||||
- When a builtin function is shadowed by a local function, you can still use
|
||||
the builtin function by specifying `builtin:`. This is especially useful
|
||||
when wrapping a builtin function:
|
||||
Nonetheless, the builtin module is also available as a
|
||||
[pre-defined module](language.html#pre-defined-modules). It can be imported with
|
||||
`use builtin`, which makes all the builtin symbols available under the
|
||||
`builtin:` namespace. This can be useful in several cases:
|
||||
|
||||
- To refer to a builtin function when it is shadowed locally. This is
|
||||
especially useful when the function that shadows the builtin one is a
|
||||
wrapper:
|
||||
|
||||
```elvish
|
||||
use builtin
|
||||
|
@ -24,7 +31,10 @@ cases where it is useful to do that:
|
|||
}
|
||||
```
|
||||
|
||||
- Introspecting the builtin module, for example `keys $builtin:`.
|
||||
Note that the shadowing of `cd` is only in effect in the local lexical
|
||||
scope.
|
||||
|
||||
- To introspect the builtin module, for example `keys $builtin:`.
|
||||
|
||||
## Usage Notation
|
||||
|
||||
|
@ -40,7 +50,7 @@ Optional arguments are represented with a trailing `?`, while variadic arguments
|
|||
with a trailing `...`. For instance, the `count` command takes an optional list:
|
||||
|
||||
```elvish
|
||||
count $input-list?
|
||||
count $inputs?
|
||||
```
|
||||
|
||||
While the `put` command takes an arbitrary number of arguments:
|
||||
|
@ -58,29 +68,36 @@ echo &sep=' ' $value...
|
|||
|
||||
(When you calling functions, options are always optional.)
|
||||
|
||||
## Supplying Input
|
||||
## Commands taking value inputs {#value-inputs}
|
||||
|
||||
Some builtin functions, e.g. `count` and `each`, can take their input in one of
|
||||
two ways:
|
||||
Most commands that take value inputs (e.g. `count`, `each`) can take the inputs
|
||||
in one of two ways:
|
||||
|
||||
1. From pipe:
|
||||
1. From the pipeline:
|
||||
|
||||
```elvish-transcript
|
||||
~> put lorem ipsum | count # count number of inputs
|
||||
2
|
||||
~> put 10 100 | each [x]{ + 1 $x } # apply function to each input
|
||||
▶ 11
|
||||
▶ 101
|
||||
~> put 10 100 | each {|x| + 1 $x } # apply function to each input
|
||||
▶ (num 11)
|
||||
▶ (num 101)
|
||||
```
|
||||
|
||||
Byte pipes are also possible; one line becomes one input:
|
||||
If the previous command outputs bytes, one line becomes one string input, as
|
||||
if there is an implicit [`from-lines`](#from-lines) (this behavior is
|
||||
subject to change):
|
||||
|
||||
```elvish-transcript
|
||||
~> echo "a\nb\nc" | count # count number of lines
|
||||
~> print "a\nb\nc\n" | count # count number of lines
|
||||
▶ 3
|
||||
~> use str
|
||||
~> print "a\nb\nc\n" | each $str:to-upper~ # apply to each line
|
||||
▶ A
|
||||
▶ B
|
||||
▶ C
|
||||
```
|
||||
|
||||
1. From an argument -- an iterable value:
|
||||
1. From an argument -- an iterable value:
|
||||
|
||||
```elvish-transcript
|
||||
~> count [lorem ipsum] # count number of elements in argument
|
||||
|
@ -90,7 +107,7 @@ two ways:
|
|||
▶ 101
|
||||
```
|
||||
|
||||
Strings, and in future, other sequence types are also possible:
|
||||
Strings, and in future, other sequence types are also supported:
|
||||
|
||||
```elvish-transcript
|
||||
~> count lorem
|
||||
|
@ -98,13 +115,11 @@ two ways:
|
|||
```
|
||||
|
||||
When documenting such commands, the optional argument is always written as
|
||||
`$input-list?`. On the other hand, a trailing `$input-list?` always indicates
|
||||
that a command can take its input in one of two ways above: this fact is not
|
||||
repeated below.
|
||||
`$inputs?`.
|
||||
|
||||
**Note**: You should prefer the first form, unless using it requires explicit
|
||||
`put` commands. Avoid `count [(some-command)]` or
|
||||
`each $some-func [(some-command)]`; they are, most of the time, equivalent to
|
||||
`each $some-func [(some-command)]`; they are equivalent to
|
||||
`some-command | count` or `some-command | each $some-func`.
|
||||
|
||||
**Rationale**: An alternative way to design this is to make (say) `count` take
|
||||
|
@ -117,7 +132,7 @@ in the argument, even if there is no file.
|
|||
|
||||
## Numeric commands
|
||||
|
||||
Anywhere a command expects a number argument, that argument can be supplied
|
||||
Wherever a command expects a number argument, that argument can be supplied
|
||||
either with a [typed number](language.html#number) or a string that can be
|
||||
converted to a number. This includes numeric comparison commands like `==`.
|
||||
|
||||
|
@ -145,7 +160,7 @@ integers or rationals), they will always output an exact number. Examples:
|
|||
▶ (num 60/17)
|
||||
```
|
||||
|
||||
If the condition above is not satisfied - i.e. when a numeric command is not
|
||||
If the condition above is not satisfied -- i.e. when a numeric command is not
|
||||
designated exactness-preserving, or when at least one of the arguments is
|
||||
inexact (i.e. a floating-point number), the result is an inexact number, unless
|
||||
otherwise documented. Examples:
|
||||
|
@ -164,13 +179,7 @@ There are some cases where the result is exact despite the use of inexact
|
|||
arguments or non-exactness-preserving commands. Such cases are always documented
|
||||
in their respective commands.
|
||||
|
||||
## Predicates
|
||||
|
||||
Predicates are functions that write exactly one output that is either `$true` or
|
||||
`$false`. They are described like "Determine ..." or "Test ...". See [`is`](#is)
|
||||
for one example.
|
||||
|
||||
## "Do Not Use" Functions and Variables
|
||||
## Unstable features
|
||||
|
||||
The name of some variables and functions have a leading `-`. This is a
|
||||
convention to say that it is subject to change and should not be depended upon.
|
||||
|
|
|
@ -695,7 +695,8 @@ bar
|
|||
```
|
||||
|
||||
If a variable is not in any of the lexical scopes, Elvish tries to resolve it in
|
||||
the `builtin:` namespace, and if that also fails, fails with an error:
|
||||
the [builtin namespace](builtin.html), and if that also fails, fails with an
|
||||
error:
|
||||
|
||||
```elvish-transcript
|
||||
~> echo $pid # builtin
|
||||
|
@ -716,9 +717,6 @@ Compilation error: variable $nonexistent not found
|
|||
[tty], line 1: echo pre-error; echo $nonexistent
|
||||
```
|
||||
|
||||
You cannot create new variables in the `builtin:` namespace, although existing
|
||||
variables in it can be assigned new values.
|
||||
|
||||
## Closure semantics
|
||||
|
||||
When a function literal refers to a variable in an outer scope, the function
|
||||
|
@ -2362,11 +2360,6 @@ The following namespaces have special meanings to the language:
|
|||
This **is** always needed, because unlike command resolution, variable
|
||||
resolution does not fall back onto environment variables.
|
||||
|
||||
- `builtin:` refers to builtin functions and variables.
|
||||
|
||||
You don't need to use this explicitly unless you have defined names that
|
||||
shadows builtin counterparts.
|
||||
|
||||
## Modules
|
||||
|
||||
Apart from the special namespaces, the most common usage of namespaces is to
|
||||
|
@ -2417,8 +2410,9 @@ use a/b/c foo # imports the "a/b/c" module as "foo:"
|
|||
Elvish's standard library provides the following pre-defined modules that can be
|
||||
imported by the `use` command:
|
||||
|
||||
- [edit](edit.html) is only available in interactive mode. As a special case
|
||||
it does not need importing via `use`, but this may change in the future.
|
||||
- [builtin](builtin.html)
|
||||
- [edit](edit.html): only available in interactive mode. As a special case it
|
||||
does not need importing via `use`, but this may change in the future.
|
||||
- [epm](epm.html)
|
||||
- [math](math.html)
|
||||
- [path](path.html)
|
||||
|
@ -2427,7 +2421,7 @@ imported by the `use` command:
|
|||
- [readline-binding](readline-binding.html)
|
||||
- [store](store.html)
|
||||
- [str](str.html)
|
||||
- [unix](unix.html) is only available on UNIX-like platforms (see
|
||||
- [unix](unix.html): only available on UNIX-like platforms (see
|
||||
[`$platform:is-unix`](platform.html#platform:is-unix))
|
||||
|
||||
### User-defined modules
|
||||
|
|
Loading…
Reference in New Issue
Block a user