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

175 lines, 79 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 parseCommand() then io->eval(), in local scope
50
51proc p {
52 var result = {}
53 for param in a b {
54 var s = """
55 proc echo_$param(prefix) {
56 echo \$prefix $param
57 }
58 """
59 var cmd = parseCommand(s)
60 call io->eval(cmd)
61 }
62
63 echo_a prefix
64 echo_b prefix
65}
66
67p
68
69echo_a prefix
70
71## status: 127
72## STDOUT:
73prefix a
74prefix b
75## END
76
77#### with parseCommand() then io->eval(cmd, vars={out_dict: {}})
78
79# This could take the place of evalToDict()? But evalToDict() is useful in
80# Hay?
81
82func genProcs() {
83 var vars = {out_dict: {}}
84 for param in a b {
85 var s = """
86 proc echo_$param(prefix) {
87 echo \$prefix $param
88 }
89 setvar out_dict.echo_$param = echo_$param
90 """
91 var cmd = parseCommand(s)
92 call io->eval(cmd, vars=vars)
93 }
94 return (vars.out_dict)
95}
96
97var procs = genProcs()
98
99var my_echo_a = procs.echo_a
100var my_echo_b = procs.echo_b
101
102my_echo_a prefix
103my_echo_b prefix
104
105## STDOUT:
106prefix a
107prefix b
108## END
109
110#### with evalToDict()
111
112func genProcs() {
113 var result = {}
114 for param in a b {
115 var s = """
116 # This is defined locally
117 proc echo_$param(prefix) {
118 echo \$prefix $param
119 }
120 if false {
121 = echo_$param
122 var a = 42
123 pp frame_vars_
124 }
125 """
126 var cmd = parseCommand(s)
127
128 var d = io->evalToDict(cmd)
129
130 # accumulate
131 setvar result["echo_$param"] = d["echo_$param"]
132 }
133 return (result)
134}
135
136var procs = genProcs()
137
138var my_echo_a = procs.echo_a
139var my_echo_b = procs.echo_b
140
141my_echo_a prefix
142my_echo_b prefix
143
144## STDOUT:
145prefix a
146prefix b
147## END
148
149
150#### with runtime REFLECTION via __invoke__ - no parsing
151
152# self is the first typed arg
153proc p (prefix; self) {
154 echo $prefix $[self.param]
155}
156
157# p is invoked with "self", which has self.param
158var methods = Object(null, {__invoke__: p})
159
160var procs = {}
161for param in a b {
162 setvar procs["echo_$param"] = Object(methods, {param: param})
163}
164
165var my_echo_a = procs.echo_a
166var my_echo_b = procs.echo_b
167
168# Maybe show an error if this is not value.Obj?
169my_echo_a prefix
170my_echo_b prefix
171
172## STDOUT:
173prefix a
174prefix b
175## END