1 # Demonstrations for users. Could go in docs.
2
3 #### GetValue scope and shopt --unset dynamic_scope
4
5 f() {
6 echo "sh x=$x"
7 }
8
9 proc p {
10 echo "oil x=$x"
11 }
12
13 demo() {
14 local x=dynamic
15 f
16 p
17
18 shopt --unset dynamic_scope
19 f
20 }
21
22 x=global
23 demo
24 echo x=$x
25
26 ## STDOUT:
27 sh x=dynamic
28 oil x=global
29 sh x=global
30 x=global
31 ## END
32
33
34 #### SetValue scope and shopt --unset dynamic_scope
35 f() {
36 x=f
37 }
38
39 proc p {
40 x=p
41 }
42
43 demo() {
44 local x=stack
45 echo x=$x
46 echo ---
47
48 f
49 echo f x=$x
50
51 x=stack
52 p
53 echo p x=$x
54
55 shopt --unset dynamic_scope
56 x=stack
57 f
58 echo funset x=$x
59 }
60
61 x=global
62 demo
63
64 echo ---
65 echo x=$x
66
67 ## STDOUT:
68 x=stack
69 ---
70 f x=f
71 p x=stack
72 funset x=stack
73 ---
74 x=global
75 ## END
76
77 #### read scope (setref)
78 read-x() {
79 echo new | read x
80 }
81 demo() {
82 local x=42
83 echo x=$x
84 read-x
85 echo x=$x
86 }
87 demo
88 echo x=$x
89
90 echo ---
91
92 shopt --unset dynamic_scope # should NOT affect read
93 demo
94 echo x=$x
95
96 ## STDOUT:
97 x=42
98 x=new
99 x=
100 ---
101 x=42
102 x=new
103 x=
104 ## END
105
106 #### printf -v scope (setref)
107 set-x() {
108 printf -v x "%s" new
109 }
110 demo() {
111 local x=42
112 echo x=$x
113 set-x
114 echo x=$x
115 }
116 demo
117 echo x=$x
118
119 echo ---
120
121 shopt --unset dynamic_scope # should NOT affect read
122 demo
123 echo x=$x
124
125 ## STDOUT:
126 x=42
127 x=new
128 x=
129 ---
130 x=42
131 x=new
132 x=
133 ## END
134
135 #### ${undef=a} and shopt --unset dynamic_scope
136
137 set-x() {
138 : ${x=new}
139 }
140 demo() {
141 local x
142 echo x=$x
143 set-x
144 echo x=$x
145 }
146
147 demo
148 echo x=$x
149
150 echo ---
151
152 # Now this IS affected?
153 shopt --unset dynamic_scope
154 demo
155 echo x=$x
156 ## STDOUT:
157 x=
158 x=new
159 x=
160 ---
161 x=
162 x=
163 x=
164 ## END
165
166 #### declare -p respects it
167 __g=G
168 show-vars() {
169 local __x=X
170 declare -p | grep '__'
171 echo status=$?
172
173 echo -
174 declare -p __y | grep '__'
175 echo status=$?
176 }
177
178 demo() {
179 local __y=Y
180
181 show-vars
182 echo ---
183 shopt --unset dynamic_scope
184 show-vars
185 }
186
187 demo
188
189 ## STDOUT:
190 declare -- __g=G
191 declare -- __x=X
192 declare -- __y=Y
193 status=0
194 -
195 declare -- __y=Y
196 status=0
197 ---
198 declare -- __g=G
199 declare -- __x=X
200 status=0
201 -
202 status=1
203 ## END
204
205
206
207 #### unset composes because it uses dynamic scope (even in Oil)
208 shopt -s oil:all
209
210 proc unset-two {
211 unset $1
212 unset $2
213 }
214
215 demo() {
216 local x=X
217 local y=Y
218
219 echo "x=$x y=$y"
220
221 unset-two x y
222
223 shopt --unset nounset
224 echo "x=$x y=$y"
225 }
226
227 demo
228 ## STDOUT:
229 x=X y=Y
230 x= y=
231 ## END
232
233
234 #### SetLocalShopt constructs
235
236 f() {
237 (( x = 42 ))
238 }
239 demo() {
240 f
241 echo x=$x
242 }
243
244 demo
245
246 echo ---
247
248 shopt --unset dynamic_scope
249
250 unset x
251
252 demo
253
254 echo --- global
255 echo x=$x
256 ## STDOUT:
257 x=42
258 ---
259 x=
260 --- global
261 x=
262 ## END
263
264
265 #### shell assignments 'neutered' inside 'proc'
266
267 # They can't mutate globals or anything higher on the stack
268
269 proc p {
270 g=PROC
271 export e=PROC
272 }
273
274 f() {
275 g=SH
276 export e=SH
277 }
278
279 e=E
280 g=G
281 p
282 echo e=$e g=$g
283
284 p
285 echo e=$e g=$g
286
287 f
288 echo e=$e g=$g
289
290 ## STDOUT:
291 e=E g=G
292 e=E g=G
293 e=SH g=SH
294 ## END
295
296 #### setvar still allows setting globals
297
298 proc p {
299 setvar new_global = 'p'
300 setvar g = 'p'
301 }
302
303 var g = 'G'
304
305 p
306
307 echo g=$g new_global=$new_global
308 ## STDOUT:
309 g=p new_global=p
310 ## END
311
312 #### setref with :out param
313
314 # The name is mangled with : so you can't use it
315 proc append(:s, suffix) {
316 setref s = "$s-$suffix"
317 }
318
319 proc set-it(:s, val) {
320 #pp cell __s
321 setref s = "foo-$val"
322 }
323
324 proc demo {
325 var s = 'abc'
326 var t = 'def'
327 set-it :s SS
328 set-it :t TT
329
330 echo $s
331 echo $t
332 }
333
334 demo
335
336 ## STDOUT:
337 foo-SS
338 foo-TT
339 ## END
340
341 #### setref without :out param
342 proc set-it(:s, val) {
343 setref val = 'oops'
344 }
345
346 var s = 'abc'
347 set-it :s SS
348 echo $s
349
350 ## status: 1
351 ## STDOUT:
352 ## END
353
354 #### setref: syntax without pgen2 using open proc
355
356 # This is kind of what we compile to. Ref params get an extra __ prefix? then
357 # that means you can't really READ them either? I think that's OK.
358
359 # At call time, param binding time:
360 # If the PARAM has a colon prefix:
361 # Assert that the ARG has a colon prefix. Don't remove it.
362 # Set the cell.nameref flag.
363 #
364 # At Setref time:
365 # Check that it's cell.nameref.
366 # Add extra : to lvalue.{Named,Indexed,Keyed} and perform it.
367 #
368 # The __ avoids the nameref cycle check.
369 # And we probably disallow reading from the ref. That's OK. The caller can
370 # pass it in as a regular value!
371
372 proc set-it {
373 local -n __s=$1 # nameref flag needed with setref
374 local val=$2
375
376 # well this part requires pgen2
377 setref s = "foo-$val"
378 }
379
380 var s = 'abc'
381 var t = 'def'
382 set-it s SS
383 set-it t TT # no colon here
384 echo $s
385 echo $t
386
387 ## STDOUT:
388 foo-SS
389 foo-TT
390 ## END
391
392 #### setref a[i]
393
394 # You can do this in bash/mksh. See nameref!
395
396 proc set1(:a, item) {
397 setref a[1] = item
398 }
399
400 var a = %(one two three)
401 var myarray = %(a b c)
402
403 set1 :a zzz
404 set1 :myarray z
405
406 shopt --set oil:basic
407 #write -- @a
408 write -- @myarray
409
410 ## STDOUT:
411 a
412 z
413 c
414 ## END