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

224 lines, 110 significant
1## oils_failures_allowed: 0
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 call io->eval(cmd)
103 }
104
105 echo_a prefix
106 echo_b prefix
107}
108
109p
110
111echo_a prefix
112
113## status: 127
114## STDOUT:
115prefix a
116prefix b
117## END
118
119#### with parseCommand() then io->eval(cmd, vars={out_dict: {}})
120
121# This could take the place of evalToDict()? But evalToDict() is useful in
122# Hay?
123
124func genProcs() {
125 var vars = {out_dict: {}}
126 for param in a b {
127 var s = """
128 proc echo_$param(prefix) {
129 echo \$prefix $param
130 }
131 setvar out_dict.echo_$param = echo_$param
132 """
133 var cmd = parseCommand(s)
134 call io->eval(cmd, vars=vars)
135 }
136 return (vars.out_dict)
137}
138
139var procs = genProcs()
140
141var my_echo_a = procs.echo_a
142var my_echo_b = procs.echo_b
143
144my_echo_a prefix
145my_echo_b prefix
146
147## STDOUT:
148prefix a
149prefix b
150## END
151
152#### with evalToDict()
153
154func genProcs() {
155 var result = {}
156 for param in a b {
157 var s = """
158 # This is defined locally
159 proc echo_$param(prefix) {
160 echo \$prefix $param
161 }
162 if false {
163 = echo_$param
164 var a = 42
165 pp frame_vars_
166 }
167 """
168 var cmd = parseCommand(s)
169
170 var d = io->evalToDict(cmd)
171
172 # accumulate
173 setvar result["echo_$param"] = d["echo_$param"]
174 }
175 return (result)
176}
177
178var procs = genProcs()
179
180var my_echo_a = procs.echo_a
181var my_echo_b = procs.echo_b
182
183my_echo_a prefix
184my_echo_b prefix
185
186## STDOUT:
187prefix a
188prefix b
189## END
190
191
192#### with runtime REFLECTION via __invoke__ - no parsing
193
194# self is the first typed arg
195proc p (prefix; self) {
196 echo $prefix $[self.param]
197}
198
199# p is invoked with "self", which has self.param
200var methods = Object(null, {__invoke__: p})
201
202var procs = {}
203for param in a b {
204 setvar procs["echo_$param"] = Object(methods, {param: param})
205}
206
207var my_echo_a = procs.echo_a
208var my_echo_b = procs.echo_b
209
210if false {
211 = my_echo_a
212 = my_echo_b
213 type -t my_echo_a
214 type -t my_echo_b
215}
216
217# Maybe show an error if this is not value.Obj?
218my_echo_a prefix
219my_echo_b prefix
220
221## STDOUT:
222prefix a
223prefix b
224## END