OILS / spec / ysh-proc-meta.test.sh View on Github | oilshell.org

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