OILS / doc / ref / chap-osh-assign.md View on Github | oils.pub

282 lines, 222 significant
1---
2title: OSH Assignment (Oils Reference)
3all_docs_url: ..
4body_css_class: width40
5default_highlighter: oils-sh
6preserve_anchor_case: yes
7---
8
9<div class="doc-ref-header">
10
11[Oils Reference](index.html) &mdash;
12Chapter **OSH Assignment**
13
14</div>
15
16This chapter describes OSH assignment, which looks like `x=value`.
17
18<span class="in-progress">(in progress)</span>
19
20<div id="dense-toc">
21</div>
22
23## Operators
24
25### sh-assign
26
27### sh-append
28
29## Compound Assignment
30
31### sh-init-list
32
33Indexed and associative arrays may be initialized by an assignment of an
34initializer list.
35
36 arr=(1 2 3 4)
37 dict=([apple]=red [banana]=yellow [orange]=orange)
38
39An initializer list does *NOT* provide a new value that will be assigned to the
40LHS of the assignment. The initializer list is rather considered *a set of
41instructions to modify the existing value of the LHS*.
42
43When the assignment is performed with `=`, the content of the LHS value is
44cleared before starting the modifications. When the assignment is performed
45with `+=`, the modifications are applied to the existing content of the LHS
46value.
47
48An initializer list has the following form: `'(' ITEMS* ')'`, where each item
49has one of the following forms:
50
51- `[KEY]=VALUE` ... This assigns `VALUE` to an element of the LHS specified by
52 `KEY`. The `VALUE` is not subject to word splitting and pathname expansions
53 as if it is the RHS of an assignment.
54- `[KEY]+=VALUE` ... This appends `VALUE` to an element of the LHS specified by
55 `KEY`. If the corresponding element does not exist, it simply assigns
56 `VALUE` to a new element associated with `KEY`. The `VALUE` is not subject
57 to word splitting and pathname expansions.
58- `VALUE` ... If the item does not have the above two forms, it is considered a
59 normal word. In this case, this assigns `VALUE` to the *next* element, where
60 the next element is determined by the LHS. Unlike the previous two forms,
61 the `VALUE` is subject to word splitting and pathname expansions as if it is
62 a normal argument to a command.
63
64The above three forms can be mixed within one initializer list, though there
65may be additional limitations depending on the type of the LHS of the
66assignment.
67
68The details of the actual modification depends on the type of the LHS. The
69assignment of an initializer list can be understood in two phases: the type of
70the LHS is first adjusted, and then the modifications to the LHS variable are
71applied.
72
73In the first phase, the type adjustment is performed in the following way:
74
75- When the LHS variable is unset, the assignment creates an empty indexed array
76 (BashArray). If the
77 assignment is performed through an assignment builtin and flag `-A` is
78 supplied to the builtin, an empty associative array (BashAssoc) is created
79 instead of an empty BashArray.
80- When the LHS is a scalar string, the assignment creates a BashArray with one
81 element, where the original value is stored at index `0`. If the assignment
82 is performed through an assignment builtin and flag `-A` is supplied to the
83 builtin, the assignment creates a BashAssoc with one element, where the
84 original value is stored at key `"0"`, instead of a BashArray.
85- When the LHS is an indexed or associative arrays, the original array is
86 directly used for the modification target. If the
87 assignment is performed through an assignment builtin and mismatching flag
88 (i.e., `-A` and `-a` for BashArray and BashAssoc, respectively) is supplied,
89 OSH discards the original array and creates a new empty BashArray (for flag
90 `-a`) or BashAssoc (for flag `-A`), while Bash issues an error preserving the
91 original array.
92- Otherwise, it is an error.
93
94These rules are summarized in the following table.
95
96<table>
97
98- thead
99 - Original LHS type
100 - Flags
101 - Result
102 - Remarks
103- tr
104 - Undef
105 - (none)
106 - an empty BashArray
107 - <!-- empty -->
108- tr
109 - <!-- empty -->
110 - `-a`
111 - an empty BashArray
112 - <!-- empty -->
113- tr
114 - <!-- empty -->
115 - `-A`
116 - an empty BashAssoc
117 - <!-- empty -->
118- tr
119 - Str
120 - (none)
121 - BashArray with one element, with the original string at index 0
122 - Error with `strict_array`
123- tr
124 - <!-- empty -->
125 - `-a`
126 - BashArray with one element, with the original string at index 0
127 - Error with `strict_array`
128- tr
129 - <!-- empty -->
130 - `-A`
131 - BashAssoc with one element, with the original string at key `"0"`
132 - Error with `strict_array`
133- tr
134 - BashArray
135 - (none)
136 - the original BashArray
137 - <!-- empty -->
138- tr
139 - <!-- empty -->
140 - `-a`
141 - the original BashArray
142 - <!-- empty -->
143- tr
144 - <!-- empty -->
145 - `-A`
146 - N/A
147 - Error
148- tr
149 - BashAssoc
150 - (none)
151 - the original BashAssoc
152 - <!-- empty -->
153- tr
154 - <!-- empty -->
155 - `-a`
156 - N/A
157 - Error
158- tr
159 - <!-- empty -->
160 - `-A`
161 - the original BashAssoc
162 - <!-- empty -->
163- tr
164 - (others)
165 - <!-- empty -->
166 - N/A
167 - Error
168
169</table>
170
171In the second phase, the modifications are applied depending on the result of
172the first phase. When the result is BashArray, see [sh-array](#sh-array).
173When the result is BashAssoc, see [sh-assoc](#sh-assoc).
174
175### sh-array
176
177When an initializer list is assigned to [BashArray][], the values will be set
178to elements of the array. For example, one may store any sequence of words,
179just like a command does:
180
181 ls $mystr "$@" *.py
182
183 # Put it in an array
184 a=(ls $mystr "$@" *.py)
185
186To explain the initialization/mutation in more detail, the array is first
187cleared if the assignment operator is `=`. Then, an element of the array is
188modified for each item in the initializer list in order. The index of the
189element to be modified is determined in the following way:
190
191- When the first initializer item does not have `[KEY]=` or `[KEY]+=`, the
192 index is the maximum existing index in the array plus one, or `0` if the
193 array is empty.
194- When the second or later initializer item does not have `[KEY]=` or
195 `[KEY]+=`, the index is larger by one than the one modified by the previous
196 initializer item.
197- When the initializer item has `[KEY]=` or `[KEY]+=`, an arithmetic evaluation
198 is applied to `KEY` to obtain the index in `BigInt`
199
200Here are examples:
201
202 declare -a a # This creates an empty array (OSH)
203 declare -a a=() # This creates an empty array
204 declare -a a=(1 2) # This creates an array with two elements: (1 2)
205
206 k=10
207 declare -a a=([k]=v 2) # This creates a sparse array with two elements,
208 # ([10]=v [11]=2)
209
210 a+=(3 4) # This appends two values to the existing array:
211 # ([10]=v [11]=2 [12]=3 [13]=4)
212 a+=([k]=5 6) # This overwrites two elements in the existing
213 # array: ([10]=5 [11]=6 [12]=3 [13]=4)
214
215In YSH, use a [list-literal][] to create a [List][] instance.
216
217[BashArray]: chap-type-method.html#BashArray
218
219[List]: chap-type-method.html#List
220[list-literal]: chap-expr-lang.html#list-literal
221
222
223### sh-assoc
224
225When an initializer list is assigned to [BashAssoc][], an associative array
226mapping a string into another string, the values will be set to elements of the
227associative array. For example, an associative array can be initialized in the
228following way:
229
230 declare -A assoc=(['k']=v ['k2']=v2)
231
232The initialization/mutation of BashAssoc is performed in a manner similar to
233BashArray. The associative array is first cleared if the assignment operator
234is `=`. Then, the modification of an element is performed for each initializer
235item in order. An item in the initializer list must be in the forms
236`[KEY]=VALUE` or `[KEY]=VALUE`. The element to be modified is specified by
237`KEY`.
238
239 declare -A a # This creates an empty BashAssoc (OSH)
240 declare -A a=() # This creates an empty BashAssoc
241 declare -A a=([a]=1 [b]=2) # This creates a BashAssoc with two elements
242
243 k=10
244 declare -A a=([k]=v) # This creates a BashAssoc with one element,
245 # (['k']=1). Unlike BashArray, "k" is not
246 # processed by arithmetic expansion.
247 a+=([a]=3 [b]=4) # This adds two elements to the original array.
248 # The result is ([a]=3 [b]=4 [k]=v)
249 a+=([k]=5) # This overwrites an element in the original
250 # array. The result is ([a]=3 [b]=4 [k]=5).
251
252As a special rule, when the first initializer form does not have `[KEY]=` or
253`[KEY]+=`, the initializer items are treated as a sequence of `KEY1 VALUE1 KEY2
254VALUE2 KEY3 VALUE3 ...`. OSH disables this feature when `strict_array` is set.
255
256 declare -A a=(1 2 3 4) # This creates a BashAssoc with two elements,
257 # ([1]=2 [3]=4)
258
259In YSH, use a [dict-literal][] to create a [Dict][] instance.
260
261[BashAssoc]: chap-type-method.html#BashAssoc
262
263[Dict]: chap-type-method.html#Dict
264[dict-literal]: chap-expr-lang.html#dict-literal
265
266## Builtins
267
268### local
269
270### readonly
271
272### export
273
274### unset
275
276### shift
277
278### declare
279
280### typeset
281
282Another name for the [declare](#declare) builtin.