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

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