OILS / spec / ysh-proc-meta.test.sh View on Github | oils.pub

267 lines, 124 significant
1## our_shell: ysh
2## oils_failures_allowed: 2
3
4# dynamically generate procs
5
6#### myproc.docString()
7
8source $[ENV.REPO_ROOT]/spec/testdata/doc-comments.sh
9
10pp test_ (myproc.docComment())
11pp test_ (getVar('proc-none').docComment())
12
13var f = get(__sh_function__, 'f')
14pp test_ (f.docComment())
15
16var g = get(__sh_function__, 'g')
17pp test_ (g.docComment())
18
19#pp proc
20
21## STDOUT:
22(Str) "YSH-style proc"
23(Null) null
24(Str) "doc ' comment with \" quotes"
25(Null) null
26## END
27
28#### Mutate __sh_function__
29
30f() { echo sh-func; }
31f
32
33setvar __sh_function__.f = 42
34
35f
36
37## STDOUT:
38sh-func
39## END
40
41
42#### with eval builtin command, in global scope
43
44for param in a b {
45 eval """
46 proc echo_$param(prefix) {
47 echo \$prefix $param
48 }
49 """
50 # We need to "escape" the for loop scope
51 call setVar("echo_$param", getVar("echo_$param"), global=true)
52}
53
54echo_a prefix
55echo_b prefix
56
57## STDOUT:
58prefix a
59prefix b
60## END
61
62#### with eval builtin command, in local scope
63
64proc p {
65 for param in a b {
66 eval """
67 proc echo_$param(prefix) {
68 echo \$prefix $param
69 }
70 """
71 # We need to "escape" the for loop scope
72 call setVar("echo_$param", getVar("echo_$param"), global=true)
73 }
74
75 # calling globals
76 echo_a prefix
77 echo_b prefix
78}
79
80p
81
82# the global is available
83echo_a prefix
84
85## STDOUT:
86prefix a
87prefix b
88prefix a
89## END
90
91#### with eval builtin command, reeturning Dict
92
93func genProcs() {
94 var result = {}
95 for param in a b {
96 eval """
97 proc echo_$param(prefix) {
98 echo \$prefix $param
99 }
100 """
101 setvar result["echo_$param"] = getVar("echo_$param")
102 }
103 return (result)
104}
105
106var procs = genProcs()
107
108# bind to global scope
109for name in (procs) {
110 call setVar("my_$name", procs[name], global=true)
111}
112
113my_echo_a prefix
114my_echo_b prefix
115
116## STDOUT:
117prefix a
118prefix b
119## END
120
121#### with parseCommand() then io->eval(), in local scope
122
123proc p {
124 var result = {}
125 for param in a b {
126 var s = """
127 proc echo_$param (prefix) {
128 echo \$prefix $param
129 }
130 """
131 var cmd = parseCommand(s)
132 #pp test_ (cmd)
133 #pp asdl_ (cmd)
134
135 # note: this creates its own frame, unlike 'eval'
136 # call io->eval(cmd)
137
138 var d = io->eval(cmd, to_dict=true)
139
140 # bind my_echo_a globally
141 call setVar("my_echo_$param", d["echo_$param"], global=true)
142 }
143
144 #= dict(vm.getFrame(0))
145
146 my_echo_a in-proc
147 my_echo_b in-proc
148}
149
150p
151
152my_echo_a global
153my_echo_b global
154
155## STDOUT:
156in-proc a
157in-proc b
158global a
159global b
160## END
161
162#### with parseCommand() then io->eval(cmd, vars={out_dict: {}})
163
164# This could take the place of evalToDict()? But evalToDict() is useful in
165# Hay?
166
167func genProcs() {
168 var vars = {out_dict: {}}
169 for param in a b {
170 var s = """
171 proc echo_$param(prefix) {
172 echo \$prefix $param
173 }
174 setvar out_dict.echo_$param = echo_$param
175 """
176 var cmd = parseCommand(s)
177 call io->eval(cmd, vars=vars)
178 }
179 return (vars.out_dict)
180}
181
182var procs = genProcs()
183
184var my_echo_a = procs.echo_a
185var my_echo_b = procs.echo_b
186
187my_echo_a prefix
188my_echo_b prefix
189
190## STDOUT:
191prefix a
192prefix b
193## END
194
195#### with evalToDict()
196
197func genProcs() {
198 var result = {}
199 for param in a b {
200 var s = """
201 # This is defined locally
202 proc echo_$param(prefix) {
203 echo \$prefix $param
204 }
205 if false {
206 = echo_$param
207 var a = 42
208 pp frame_vars_
209 }
210 """
211 var cmd = parseCommand(s)
212
213 var d = io->evalToDict(cmd)
214
215 # accumulate
216 setvar result["echo_$param"] = d["echo_$param"]
217 }
218 return (result)
219}
220
221var procs = genProcs()
222
223var my_echo_a = procs.echo_a
224var my_echo_b = procs.echo_b
225
226my_echo_a prefix
227my_echo_b prefix
228
229## STDOUT:
230prefix a
231prefix b
232## END
233
234
235#### with runtime REFLECTION via __invoke__ - no parsing
236
237# self is the first typed arg
238proc p (prefix; self) {
239 echo $prefix $[self.param]
240}
241
242# p is invoked with "self", which has self.param
243var methods = Object(null, {__invoke__: p})
244
245var procs = {}
246for param in a b {
247 setvar procs["echo_$param"] = Object(methods, {param: param})
248}
249
250var my_echo_a = procs.echo_a
251var my_echo_b = procs.echo_b
252
253if false {
254 = my_echo_a
255 = my_echo_b
256 type -t my_echo_a
257 type -t my_echo_b
258}
259
260# Maybe show an error if this is not value.Obj?
261my_echo_a prefix
262my_echo_b prefix
263
264## STDOUT:
265prefix a
266prefix b
267## END