Why Sponsor Oils? | source | all docs for version 0.32.0 | all versions | oils.pub
Oils Reference — Chapter OSH Assignment
This chapter describes OSH assignment, which looks like x=value
.
(in progress)
Indexed and associative arrays may be initialized by an assignment of an initializer list.
arr=(1 2 3 4)
dict=([apple]=red [banana]=yellow [orange]=orange)
An initializer list does NOT provide a new value that will be assigned to the LHS of the assignment. The initializer list is rather considered a set of instructions to modify the existing value of the LHS.
When the assignment is performed with =
, the content of the LHS value is
cleared before starting the modifications. When the assignment is performed
with +=
, the modifications are applied to the existing content of the LHS
value.
An initializer list has the following form: '(' ITEMS* ')'
, where each item
has one of the following forms:
[KEY]=VALUE
... This assigns VALUE
to an element of the LHS specified by
KEY
. The VALUE
is not subject to word splitting and pathname expansions
as if it is the RHS of an assignment.[KEY]+=VALUE
... This appends VALUE
to an element of the LHS specified by
KEY
. If the corresponding element does not exist, it simply assigns
VALUE
to a new element associated with KEY
. The VALUE
is not subject
to word splitting and pathname expansions.VALUE
... If the item does not have the above two forms, it is considered a
normal word. In this case, this assigns VALUE
to the next element, where
the next element is determined by the LHS. Unlike the previous two forms,
the VALUE
is subject to word splitting and pathname expansions as if it is
a normal argument to a command.The above three forms can be mixed within one initializer list, though there may be additional limitations depending on the type of the LHS of the assignment.
The details of the actual modification depends on the type of the LHS. The assignment of an initializer list can be understood in two phases: the type of the LHS is first adjusted, and then the modifications to the LHS variable are applied.
In the first phase, the type adjustment is performed in the following way:
-A
is
supplied to the builtin, an empty associative array (BashAssoc) is created
instead of an empty BashArray.0
. If the assignment
is performed through an assignment builtin and flag -A
is supplied to the
builtin, the assignment creates a BashAssoc with one element, where the
original value is stored at key "0"
, instead of a BashArray.-A
and -a
for BashArray and BashAssoc, respectively) is supplied,
OSH discards the original array and creates a new empty BashArray (for flag
-a
) or BashAssoc (for flag -A
), while Bash issues an error preserving the
original array.These rules are summarized in the following table.
Original LHS type | Flags | Result | Remarks |
---|---|---|---|
Undef | (none) | an empty BashArray | |
-a |
an empty BashArray | ||
-A |
an empty BashAssoc | ||
Str | (none) | BashArray with one element, with the original string at index 0 | Error with strict_array |
-a |
BashArray with one element, with the original string at index 0 | Error with strict_array |
|
-A |
BashAssoc with one element, with the original string at key "0" |
Error with strict_array |
|
BashArray | (none) | the original BashArray | |
-a |
the original BashArray | ||
-A |
N/A | Error | |
BashAssoc | (none) | the original BashAssoc | |
-a |
N/A | Error | |
-A |
the original BashAssoc | ||
(others) | N/A | Error |
In the second phase, the modifications are applied depending on the result of the first phase. When the result is BashArray, see sh-array. When the result is BashAssoc, see sh-assoc.
When an initializer list is assigned to BashArray, the values will be set to elements of the array. For example, one may store any sequence of words, just like a command does:
ls $mystr "$@" *.py
# Put it in an array
a=(ls $mystr "$@" *.py)
To explain the initialization/mutation in more detail, the array is first
cleared if the assignment operator is =
. Then, an element of the array is
modified for each item in the initializer list in order. The index of the
element to be modified is determined in the following way:
[KEY]=
or [KEY]+=
, the
index is the maximum existing index in the array plus one, or 0
if the
array is empty.[KEY]=
or
[KEY]+=
, the index is larger by one than the one modified by the previous
initializer item.[KEY]=
or [KEY]+=
, an arithmetic evaluation
is applied to KEY
to obtain the index in BigInt
Here are examples:
declare -a a # This creates an empty array (OSH)
declare -a a=() # This creates an empty array
declare -a a=(1 2) # This creates an array with two elements: (1 2)
k=10
declare -a a=([k]=v 2) # This creates a sparse array with two elements,
# ([10]=v [11]=2)
a+=(3 4) # This appends two values to the existing array:
# ([10]=v [11]=2 [12]=3 [13]=4)
a+=([k]=5 6) # This overwrites two elements in the existing
# array: ([10]=5 [11]=6 [12]=3 [13]=4)
In YSH, use a list-literal to create a List instance.
When an initializer list is assigned to BashAssoc, an associative array mapping a string into another string, the values will be set to elements of the associative array. For example, an associative array can be initialized in the following way:
declare -A assoc=(['k']=v ['k2']=v2)
The initialization/mutation of BashAssoc is performed in a manner similar to
BashArray. The associative array is first cleared if the assignment operator
is =
. Then, the modification of an element is performed for each initializer
item in order. An item in the initializer list must be in the forms
[KEY]=VALUE
or [KEY]=VALUE
. The element to be modified is specified by
KEY
.
declare -A a # This creates an empty BashAssoc (OSH)
declare -A a=() # This creates an empty BashAssoc
declare -A a=([a]=1 [b]=2) # This creates a BashAssoc with two elements
k=10
declare -A a=([k]=v) # This creates a BashAssoc with one element,
# (['k']=1). Unlike BashArray, "k" is not
# processed by arithmetic expansion.
a+=([a]=3 [b]=4) # This adds two elements to the original array.
# The result is ([a]=3 [b]=4 [k]=v)
a+=([k]=5) # This overwrites an element in the original
# array. The result is ([a]=3 [b]=4 [k]=5).
As a special rule, when the first initializer form does not have [KEY]=
or
[KEY]+=
, the initializer items are treated as a sequence of KEY1 VALUE1 KEY2 VALUE2 KEY3 VALUE3 ...
. OSH disables this feature when strict_array
is set.
declare -A a=(1 2 3 4) # This creates a BashAssoc with two elements,
# ([1]=2 [3]=4)
In YSH, use a dict-literal to create a Dict instance.
Another name for the declare builtin.