code-ruby 4.0.0 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/bin/code +8 -5
- data/lib/code/concerns/shared.rb +102 -98
- data/lib/code/format.rb +23 -19
- data/lib/code/network.rb +23 -28
- data/lib/code/node/call.rb +9 -8
- data/lib/code/node/code.rb +1 -1
- data/lib/code/node/list.rb +10 -8
- data/lib/code/node/square_bracket.rb +4 -2
- data/lib/code/object/boolean.rb +13 -17
- data/lib/code/object/class.rb +32 -27
- data/lib/code/object/code.rb +2 -9
- data/lib/code/object/context.rb +4 -2
- data/lib/code/object/cryptography.rb +12 -6
- data/lib/code/object/date.rb +910 -449
- data/lib/code/object/decimal.rb +229 -856
- data/lib/code/object/dictionary.rb +113 -42
- data/lib/code/object/duration.rb +3 -7
- data/lib/code/object/function.rb +64 -40
- data/lib/code/object/global.rb +121 -208
- data/lib/code/object/html.rb +4 -2
- data/lib/code/object/http.rb +32 -26
- data/lib/code/object/ics.rb +2 -1
- data/lib/code/object/identifier_list.rb +16 -11
- data/lib/code/object/integer.rb +270 -942
- data/lib/code/object/json.rb +8 -3
- data/lib/code/object/list.rb +97 -109
- data/lib/code/object/nothing.rb +11 -11
- data/lib/code/object/number.rb +20 -10
- data/lib/code/object/parameter.rb +18 -9
- data/lib/code/object/range.rb +62 -108
- data/lib/code/object/smtp.rb +20 -12
- data/lib/code/object/string.rb +52 -28
- data/lib/code/object/super.rb +2 -1
- data/lib/code/object/time.rb +1146 -572
- data/lib/code/object/url.rb +4 -2
- data/lib/code/object.rb +119 -80
- data/lib/code/parser.rb +34 -32
- metadata +1 -1
|
@@ -5,7 +5,8 @@ class Code
|
|
|
5
5
|
class Dictionary < ::Code::Object
|
|
6
6
|
CLASS_DOCUMENTATION = {
|
|
7
7
|
name: "Dictionary",
|
|
8
|
-
description:
|
|
8
|
+
description:
|
|
9
|
+
"stores keyed values and provides lookup, merge, and enumerable operations.",
|
|
9
10
|
examples: [
|
|
10
11
|
"{ a: 1 }",
|
|
11
12
|
"Dictionary.from_entries([[:a, 1]])",
|
|
@@ -59,16 +60,25 @@ class Code
|
|
|
59
60
|
"at" => {
|
|
60
61
|
name: "at",
|
|
61
62
|
description: "alias for get.",
|
|
62
|
-
examples: [
|
|
63
|
+
examples: [
|
|
64
|
+
"{ a: 1 }.at(:a)",
|
|
65
|
+
"{ a: 1 }.at(:b)",
|
|
66
|
+
"{ a: 1, b: 2 }.at(:b)"
|
|
67
|
+
]
|
|
63
68
|
},
|
|
64
69
|
"get" => {
|
|
65
70
|
name: "get",
|
|
66
71
|
description: "returns the value for a key, otherwise nothing.",
|
|
67
|
-
examples: [
|
|
72
|
+
examples: [
|
|
73
|
+
"{ a: 1 }.get(:a)",
|
|
74
|
+
"{ a: 1 }.get(:b)",
|
|
75
|
+
"{ a: 1, b: 2 }.get(:b)"
|
|
76
|
+
]
|
|
68
77
|
},
|
|
69
78
|
"any?" => {
|
|
70
79
|
name: "any?",
|
|
71
|
-
description:
|
|
80
|
+
description:
|
|
81
|
+
"returns whether any entry exists, has a class value, or matches a function.",
|
|
72
82
|
examples: [
|
|
73
83
|
"{ a: 1 }.any?",
|
|
74
84
|
"{}.any?",
|
|
@@ -77,12 +87,14 @@ class Code
|
|
|
77
87
|
},
|
|
78
88
|
"clear" => {
|
|
79
89
|
name: "clear",
|
|
80
|
-
description:
|
|
90
|
+
description:
|
|
91
|
+
"removes every entry from the dictionary and returns it.",
|
|
81
92
|
examples: ["{ a: 1 }.clear", "{ a: 1, b: 2 }.clear", "{}.clear"]
|
|
82
93
|
},
|
|
83
94
|
"compact" => {
|
|
84
95
|
name: "compact",
|
|
85
|
-
description:
|
|
96
|
+
description:
|
|
97
|
+
"returns a dictionary without nothing values or matching values.",
|
|
86
98
|
examples: [
|
|
87
99
|
"{ a: 1, b: nothing }.compact",
|
|
88
100
|
"{ a: 1, b: :x }.compact(String)",
|
|
@@ -91,7 +103,8 @@ class Code
|
|
|
91
103
|
},
|
|
92
104
|
"compact!" => {
|
|
93
105
|
name: "compact!",
|
|
94
|
-
description:
|
|
106
|
+
description:
|
|
107
|
+
"removes nothing values or matching values from the dictionary.",
|
|
95
108
|
examples: [
|
|
96
109
|
"{ a: 1, b: nothing }.compact!",
|
|
97
110
|
"{ a: 1, b: :x }.compact!(String)",
|
|
@@ -136,7 +149,8 @@ class Code
|
|
|
136
149
|
},
|
|
137
150
|
"each" => {
|
|
138
151
|
name: "each",
|
|
139
|
-
description:
|
|
152
|
+
description:
|
|
153
|
+
"calls a function for each key-value pair and returns the dictionary.",
|
|
140
154
|
examples: [
|
|
141
155
|
"{ a: 1 }.each((key, value) => { value })",
|
|
142
156
|
"{ a: 1 }.each((key, value, index) => { index })",
|
|
@@ -145,7 +159,8 @@ class Code
|
|
|
145
159
|
},
|
|
146
160
|
"each_key" => {
|
|
147
161
|
name: "each_key",
|
|
148
|
-
description:
|
|
162
|
+
description:
|
|
163
|
+
"calls a function for each key and returns the dictionary.",
|
|
149
164
|
examples: [
|
|
150
165
|
"{ a: 1 }.each_key((key) => { key })",
|
|
151
166
|
"{ a: 1, b: 2 }.each_key((key, index) => { index })",
|
|
@@ -154,7 +169,8 @@ class Code
|
|
|
154
169
|
},
|
|
155
170
|
"each_value" => {
|
|
156
171
|
name: "each_value",
|
|
157
|
-
description:
|
|
172
|
+
description:
|
|
173
|
+
"calls a function for each value and returns the dictionary.",
|
|
158
174
|
examples: [
|
|
159
175
|
"{ a: 1 }.each_value((value) => { value })",
|
|
160
176
|
"{ a: 1, b: 2 }.each_value((value, index) => { index })",
|
|
@@ -163,7 +179,8 @@ class Code
|
|
|
163
179
|
},
|
|
164
180
|
"each_pair" => {
|
|
165
181
|
name: "each_pair",
|
|
166
|
-
description:
|
|
182
|
+
description:
|
|
183
|
+
"calls a function for each key-value pair and returns the dictionary.",
|
|
167
184
|
examples: [
|
|
168
185
|
"{ a: 1 }.each_pair((key, value) => { value })",
|
|
169
186
|
"{ a: 1, b: 2 }.each_pair((key, value, index) => { index })",
|
|
@@ -204,13 +221,22 @@ class Code
|
|
|
204
221
|
},
|
|
205
222
|
"flatten" => {
|
|
206
223
|
name: "flatten",
|
|
207
|
-
description:
|
|
208
|
-
|
|
224
|
+
description:
|
|
225
|
+
"returns a flattened list of dictionary keys and values.",
|
|
226
|
+
examples: [
|
|
227
|
+
"{ a: 1 }.flatten",
|
|
228
|
+
"{ a: { b: 1 } }.flatten",
|
|
229
|
+
"{ a: 1 }.flatten(1)"
|
|
230
|
+
]
|
|
209
231
|
},
|
|
210
232
|
"has_key?" => {
|
|
211
233
|
name: "has_key?",
|
|
212
234
|
description: "returns whether the dictionary contains a key.",
|
|
213
|
-
examples: [
|
|
235
|
+
examples: [
|
|
236
|
+
"{ a: 1 }.has_key?(:a)",
|
|
237
|
+
"{ a: 1 }.has_key?(:b)",
|
|
238
|
+
"{}.has_key?(:a)"
|
|
239
|
+
]
|
|
214
240
|
},
|
|
215
241
|
"key?" => {
|
|
216
242
|
name: "key?",
|
|
@@ -220,17 +246,29 @@ class Code
|
|
|
220
246
|
"include?" => {
|
|
221
247
|
name: "include?",
|
|
222
248
|
description: "alias for has_key?.",
|
|
223
|
-
examples: [
|
|
249
|
+
examples: [
|
|
250
|
+
"{ a: 1 }.include?(:a)",
|
|
251
|
+
"{ a: 1 }.include?(:b)",
|
|
252
|
+
"{}.include?(:a)"
|
|
253
|
+
]
|
|
224
254
|
},
|
|
225
255
|
"member?" => {
|
|
226
256
|
name: "member?",
|
|
227
257
|
description: "alias for has_key?.",
|
|
228
|
-
examples: [
|
|
258
|
+
examples: [
|
|
259
|
+
"{ a: 1 }.member?(:a)",
|
|
260
|
+
"{ a: 1 }.member?(:b)",
|
|
261
|
+
"{}.member?(:a)"
|
|
262
|
+
]
|
|
229
263
|
},
|
|
230
264
|
"has_own?" => {
|
|
231
265
|
name: "has_own?",
|
|
232
266
|
description: "returns whether the dictionary contains a key.",
|
|
233
|
-
examples: [
|
|
267
|
+
examples: [
|
|
268
|
+
"{ a: 1 }.has_own?(:a)",
|
|
269
|
+
"{ a: 1 }.has_own?(:b)",
|
|
270
|
+
"{}.has_own?(:a)"
|
|
271
|
+
]
|
|
234
272
|
},
|
|
235
273
|
"has_value?" => {
|
|
236
274
|
name: "has_value?",
|
|
@@ -271,7 +309,8 @@ class Code
|
|
|
271
309
|
},
|
|
272
310
|
"key" => {
|
|
273
311
|
name: "key",
|
|
274
|
-
description:
|
|
312
|
+
description:
|
|
313
|
+
"returns the first key for a value, or a fallback result.",
|
|
275
314
|
examples: [
|
|
276
315
|
"{ a: 1 }.key(1)",
|
|
277
316
|
"{ a: 1, b: 2 }.key(2)",
|
|
@@ -321,7 +360,8 @@ class Code
|
|
|
321
360
|
},
|
|
322
361
|
"replace" => {
|
|
323
362
|
name: "replace",
|
|
324
|
-
description:
|
|
363
|
+
description:
|
|
364
|
+
"replaces the dictionary contents with another dictionary.",
|
|
325
365
|
examples: [
|
|
326
366
|
"{ a: 1 }.replace({ b: 2 })",
|
|
327
367
|
"{ a: 1, b: 2 }.replace({})",
|
|
@@ -344,7 +384,8 @@ class Code
|
|
|
344
384
|
},
|
|
345
385
|
"reject" => {
|
|
346
386
|
name: "reject",
|
|
347
|
-
description:
|
|
387
|
+
description:
|
|
388
|
+
"returns a dictionary without entries matching a function.",
|
|
348
389
|
examples: [
|
|
349
390
|
"{ a: 1, b: 2 }.reject((key, value) => { value > 1 })",
|
|
350
391
|
"{ a: 1 }.reject((key) => { key == :a })",
|
|
@@ -399,7 +440,11 @@ class Code
|
|
|
399
440
|
"set" => {
|
|
400
441
|
name: "set",
|
|
401
442
|
description: "sets a key to a value and returns the value.",
|
|
402
|
-
examples: [
|
|
443
|
+
examples: [
|
|
444
|
+
"{ a: 1 }.set(:b, 2)",
|
|
445
|
+
"{}.set(:a, 1)",
|
|
446
|
+
"{ a: 1 }.set(:a, 2)"
|
|
447
|
+
]
|
|
403
448
|
},
|
|
404
449
|
"size" => {
|
|
405
450
|
name: "size",
|
|
@@ -442,7 +487,11 @@ class Code
|
|
|
442
487
|
"to_context" => {
|
|
443
488
|
name: "to_context",
|
|
444
489
|
description: "converts the dictionary to a context.",
|
|
445
|
-
examples: [
|
|
490
|
+
examples: [
|
|
491
|
+
"{ a: 1 }.to_context",
|
|
492
|
+
"{ a: 1, b: 2 }.to_context",
|
|
493
|
+
"{}.to_context"
|
|
494
|
+
]
|
|
446
495
|
},
|
|
447
496
|
"to_query" => {
|
|
448
497
|
name: "to_query",
|
|
@@ -455,7 +504,8 @@ class Code
|
|
|
455
504
|
},
|
|
456
505
|
"transform_keys" => {
|
|
457
506
|
name: "transform_keys",
|
|
458
|
-
description:
|
|
507
|
+
description:
|
|
508
|
+
"returns a dictionary with keys transformed by a function.",
|
|
459
509
|
examples: [
|
|
460
510
|
"{ a: 1 }.transform_keys((key) => { key.to_string })",
|
|
461
511
|
"{ a: 1 }.transform_keys((key, value) => { value })",
|
|
@@ -473,7 +523,8 @@ class Code
|
|
|
473
523
|
},
|
|
474
524
|
"transform_values" => {
|
|
475
525
|
name: "transform_values",
|
|
476
|
-
description:
|
|
526
|
+
description:
|
|
527
|
+
"returns a dictionary with values transformed by a key-value function.",
|
|
477
528
|
examples: [
|
|
478
529
|
"{ a: 1 }.transform_values((key, value) => { value + 1 })",
|
|
479
530
|
"{ a: 1 }.transform_values((key, value) => { key })",
|
|
@@ -482,7 +533,8 @@ class Code
|
|
|
482
533
|
},
|
|
483
534
|
"transform_values!" => {
|
|
484
535
|
name: "transform_values!",
|
|
485
|
-
description:
|
|
536
|
+
description:
|
|
537
|
+
"transforms values in the receiver with a key-value function.",
|
|
486
538
|
examples: [
|
|
487
539
|
"{ a: 1 }.transform_values!((key, value) => { value + 1 })",
|
|
488
540
|
"{ a: 1 }.transform_values!((key, value) => { key })",
|
|
@@ -509,7 +561,8 @@ class Code
|
|
|
509
561
|
},
|
|
510
562
|
"associate" => {
|
|
511
563
|
name: "associate",
|
|
512
|
-
description:
|
|
564
|
+
description:
|
|
565
|
+
"returns the key-value entry for a key, otherwise nothing.",
|
|
513
566
|
examples: [
|
|
514
567
|
"{ a: 1 }.associate(:a)",
|
|
515
568
|
"{ a: 1, b: 2 }.associate(:b)",
|
|
@@ -518,7 +571,8 @@ class Code
|
|
|
518
571
|
},
|
|
519
572
|
"right_associate" => {
|
|
520
573
|
name: "right_associate",
|
|
521
|
-
description:
|
|
574
|
+
description:
|
|
575
|
+
"returns the first key-value entry for a value, otherwise nothing.",
|
|
522
576
|
examples: [
|
|
523
577
|
"{ a: 1 }.right_associate(1)",
|
|
524
578
|
"{ a: 1, b: 2 }.right_associate(2)",
|
|
@@ -536,27 +590,32 @@ class Code
|
|
|
536
590
|
},
|
|
537
591
|
"many?" => {
|
|
538
592
|
name: "many?",
|
|
539
|
-
description:
|
|
593
|
+
description:
|
|
594
|
+
"returns whether the dictionary has more than one entry.",
|
|
540
595
|
examples: ["{ a: 1, b: 2 }.many?", "{ a: 1 }.many?", "{}.many?"]
|
|
541
596
|
},
|
|
542
597
|
"positive?" => {
|
|
543
598
|
name: "positive?",
|
|
544
599
|
description: "returns whether the dictionary size is positive.",
|
|
545
|
-
examples: [
|
|
600
|
+
examples: [
|
|
601
|
+
"{ a: 1 }.positive?",
|
|
602
|
+
"{}.positive?",
|
|
603
|
+
"{ a: 1, b: 2 }.positive?"
|
|
604
|
+
]
|
|
546
605
|
},
|
|
547
606
|
"negative?" => {
|
|
548
607
|
name: "negative?",
|
|
549
608
|
description: "returns whether the dictionary size is negative.",
|
|
550
|
-
examples: [
|
|
609
|
+
examples: [
|
|
610
|
+
"{}.negative?",
|
|
611
|
+
"{ a: 1 }.negative?",
|
|
612
|
+
"{ a: 1, b: 2 }.negative?"
|
|
613
|
+
]
|
|
551
614
|
},
|
|
552
615
|
"zero?" => {
|
|
553
616
|
name: "zero?",
|
|
554
617
|
description: "returns whether the dictionary size is zero.",
|
|
555
|
-
examples: [
|
|
556
|
-
"{}.zero?",
|
|
557
|
-
"{ a: 1 }.zero?",
|
|
558
|
-
"{ a: 1, b: 2 }.zero?"
|
|
559
|
-
]
|
|
618
|
+
examples: ["{}.zero?", "{ a: 1 }.zero?", "{ a: 1, b: 2 }.zero?"]
|
|
560
619
|
},
|
|
561
620
|
"one?" => {
|
|
562
621
|
name: "one?",
|
|
@@ -2149,7 +2208,12 @@ class Code
|
|
|
2149
2208
|
end
|
|
2150
2209
|
|
|
2151
2210
|
def self.code_assign(*dictionaries)
|
|
2152
|
-
Dictionary.new(
|
|
2211
|
+
Dictionary.new(
|
|
2212
|
+
dictionaries
|
|
2213
|
+
.to_code
|
|
2214
|
+
.raw
|
|
2215
|
+
.reduce({}) { |acc, item| acc.merge(item.raw) }
|
|
2216
|
+
)
|
|
2153
2217
|
end
|
|
2154
2218
|
|
|
2155
2219
|
def self.code_has_own?(dictionary, key)
|
|
@@ -2519,7 +2583,8 @@ class Code
|
|
|
2519
2583
|
List.new(
|
|
2520
2584
|
raw.map.with_index do |(key, value), index|
|
|
2521
2585
|
code_function.call(
|
|
2522
|
-
arguments:
|
|
2586
|
+
arguments:
|
|
2587
|
+
List.new([key.to_code, value.to_code, index.to_code, self]),
|
|
2523
2588
|
**globals
|
|
2524
2589
|
)
|
|
2525
2590
|
rescue Error::Next => e
|
|
@@ -2687,7 +2752,8 @@ class Code
|
|
|
2687
2752
|
else
|
|
2688
2753
|
raw.reject!.with_index do |(key, value), index|
|
|
2689
2754
|
code_argument.call(
|
|
2690
|
-
arguments:
|
|
2755
|
+
arguments:
|
|
2756
|
+
List.new([key.to_code, value.to_code, index.to_code, self]),
|
|
2691
2757
|
**globals
|
|
2692
2758
|
).truthy?
|
|
2693
2759
|
rescue Error::Next => e
|
|
@@ -2704,12 +2770,15 @@ class Code
|
|
|
2704
2770
|
code_argument = argument.to_code
|
|
2705
2771
|
|
|
2706
2772
|
if code_argument.is_a?(Class)
|
|
2707
|
-
Dictionary.new(
|
|
2773
|
+
Dictionary.new(
|
|
2774
|
+
raw.reject { |_, value| value.is_a?(code_argument.raw) }
|
|
2775
|
+
)
|
|
2708
2776
|
else
|
|
2709
2777
|
Dictionary.new(
|
|
2710
2778
|
raw.reject.with_index do |(key, value), index|
|
|
2711
2779
|
code_argument.call(
|
|
2712
|
-
arguments:
|
|
2780
|
+
arguments:
|
|
2781
|
+
List.new([key.to_code, value.to_code, index.to_code, self]),
|
|
2713
2782
|
**globals
|
|
2714
2783
|
).truthy?
|
|
2715
2784
|
rescue Error::Next => e
|
|
@@ -2764,7 +2833,8 @@ class Code
|
|
|
2764
2833
|
.with_index do |(key, value), index|
|
|
2765
2834
|
[
|
|
2766
2835
|
code_function.call(
|
|
2767
|
-
arguments:
|
|
2836
|
+
arguments:
|
|
2837
|
+
List.new([key.to_code, value.to_code, index.to_code, self]),
|
|
2768
2838
|
**globals
|
|
2769
2839
|
),
|
|
2770
2840
|
value.to_code
|
|
@@ -2832,7 +2902,8 @@ class Code
|
|
|
2832
2902
|
List.new(
|
|
2833
2903
|
entries.map.with_index do |(key, value), index|
|
|
2834
2904
|
code_function.call(
|
|
2835
|
-
arguments:
|
|
2905
|
+
arguments:
|
|
2906
|
+
List.new([key.to_code, value.to_code, index.to_code, self]),
|
|
2836
2907
|
**globals
|
|
2837
2908
|
)
|
|
2838
2909
|
rescue Error::Next => e
|
data/lib/code/object/duration.rb
CHANGED
|
@@ -6,22 +6,18 @@ class Code
|
|
|
6
6
|
CLASS_DOCUMENTATION = {
|
|
7
7
|
name: "Duration",
|
|
8
8
|
description: "stores a length of time for shifting dates and times.",
|
|
9
|
-
examples: [
|
|
10
|
-
"1.day",
|
|
11
|
-
"2.hours",
|
|
12
|
-
"Duration.new(\"P1D\")"
|
|
13
|
-
]
|
|
9
|
+
examples: ["1.day", "2.hours", "Duration.new(\"P1D\")"]
|
|
14
10
|
}.freeze
|
|
15
11
|
INSTANCE_FUNCTIONS = {
|
|
16
12
|
"ago" => {
|
|
17
13
|
name: "ago",
|
|
18
14
|
description: "returns the current time minus this duration.",
|
|
19
|
-
examples: [
|
|
15
|
+
examples: %w[1.day.ago 2.hours.ago 30.minutes.ago]
|
|
20
16
|
},
|
|
21
17
|
"from_now" => {
|
|
22
18
|
name: "from_now",
|
|
23
19
|
description: "returns the current time plus this duration.",
|
|
24
|
-
examples: [
|
|
20
|
+
examples: %w[1.day.from_now 2.hours.from_now 30.minutes.from_now]
|
|
25
21
|
}
|
|
26
22
|
}.freeze
|
|
27
23
|
|
data/lib/code/object/function.rb
CHANGED
|
@@ -5,7 +5,8 @@ class Code
|
|
|
5
5
|
class Function < Object
|
|
6
6
|
CLASS_DOCUMENTATION = {
|
|
7
7
|
name: "Function",
|
|
8
|
-
description:
|
|
8
|
+
description:
|
|
9
|
+
"stores a callable block with parameters, captured context, and documentation.",
|
|
9
10
|
examples: [
|
|
10
11
|
"Function.new",
|
|
11
12
|
"((value) => { value + 1 }).call(1)",
|
|
@@ -15,7 +16,8 @@ class Code
|
|
|
15
16
|
INSTANCE_FUNCTIONS = {
|
|
16
17
|
"call" => {
|
|
17
18
|
name: "call",
|
|
18
|
-
description:
|
|
19
|
+
description:
|
|
20
|
+
"evaluates the function body with the provided arguments.",
|
|
19
21
|
examples: [
|
|
20
22
|
"((value) => { value + 1 }).call(1)",
|
|
21
23
|
"((name:) => { name }).call(name: :ada)",
|
|
@@ -24,7 +26,8 @@ class Code
|
|
|
24
26
|
},
|
|
25
27
|
"extend" => {
|
|
26
28
|
name: "extend",
|
|
27
|
-
description:
|
|
29
|
+
description:
|
|
30
|
+
"creates a child function that can call the receiver through super.",
|
|
28
31
|
examples: [
|
|
29
32
|
"Base = () => { self.name = :base } Child = Base.extend(() => { super() }) Child().name",
|
|
30
33
|
"Base = () => { 1 } Child = Base.extend(() => { super() }) Child()",
|
|
@@ -33,7 +36,8 @@ class Code
|
|
|
33
36
|
},
|
|
34
37
|
"documentation" => {
|
|
35
38
|
name: "documentation",
|
|
36
|
-
description:
|
|
39
|
+
description:
|
|
40
|
+
"returns or replaces the function documentation dictionary.",
|
|
37
41
|
examples: [
|
|
38
42
|
"f = () => { 1 } f.documentation",
|
|
39
43
|
"f = () => { 1 } f.documentation(description: \"returns one\", examples: [\"f()\"])",
|
|
@@ -51,7 +55,8 @@ class Code
|
|
|
51
55
|
},
|
|
52
56
|
"parameters" => {
|
|
53
57
|
name: "parameters",
|
|
54
|
-
description:
|
|
58
|
+
description:
|
|
59
|
+
"returns a list of parameter descriptors for the function.",
|
|
55
60
|
examples: [
|
|
56
61
|
"((name) => { name }).parameters.first.name",
|
|
57
62
|
"((name = :a) => { name }).parameters.first.default",
|
|
@@ -76,8 +81,11 @@ class Code
|
|
|
76
81
|
end
|
|
77
82
|
|
|
78
83
|
attr_accessor :documentation
|
|
79
|
-
attr_reader :code_parameters,
|
|
80
|
-
:
|
|
84
|
+
attr_reader :code_parameters,
|
|
85
|
+
:code_body,
|
|
86
|
+
:definition_context,
|
|
87
|
+
:instance_functions,
|
|
88
|
+
:parent
|
|
81
89
|
|
|
82
90
|
def initialize(*args, parent: nil, functions: nil, **_kargs, &_block)
|
|
83
91
|
@code_parameters =
|
|
@@ -93,11 +101,12 @@ class Code
|
|
|
93
101
|
self.functions = functions.to_code
|
|
94
102
|
self.functions = Dictionary.new if self.functions.nothing?
|
|
95
103
|
@instance_functions = Dictionary.new
|
|
96
|
-
self.documentation =
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
104
|
+
self.documentation =
|
|
105
|
+
Dictionary.new(
|
|
106
|
+
"name" => String.new(""),
|
|
107
|
+
"description" => String.new(""),
|
|
108
|
+
"examples" => List.new
|
|
109
|
+
)
|
|
101
110
|
|
|
102
111
|
self.raw = List.new([code_parameters, code_body])
|
|
103
112
|
end
|
|
@@ -186,7 +195,9 @@ class Code
|
|
|
186
195
|
end
|
|
187
196
|
|
|
188
197
|
captures_function_arguments =
|
|
189
|
-
code_parameters.raw.any?
|
|
198
|
+
code_parameters.raw.any? do |parameter|
|
|
199
|
+
parameter.block? || parameter.blocks?
|
|
200
|
+
end
|
|
190
201
|
reserved_function_arguments =
|
|
191
202
|
captures_function_arguments ? code_arguments.raw.grep(Function) : []
|
|
192
203
|
code_block_argument =
|
|
@@ -206,16 +217,20 @@ class Code
|
|
|
206
217
|
end
|
|
207
218
|
)
|
|
208
219
|
elsif code_parameter.keyword_splat?
|
|
209
|
-
code_arguments
|
|
210
|
-
|
|
211
|
-
|
|
220
|
+
code_arguments
|
|
221
|
+
.raw
|
|
222
|
+
.grep(Dictionary)
|
|
223
|
+
.inject(Dictionary.new) do |memo, argument|
|
|
224
|
+
memo.code_merge!(argument)
|
|
225
|
+
end
|
|
212
226
|
elsif code_parameter.block?
|
|
213
227
|
code_block_argument.to_code
|
|
214
228
|
elsif code_parameter.blocks?
|
|
215
229
|
Object::List.new(
|
|
216
|
-
code_arguments
|
|
217
|
-
|
|
218
|
-
|
|
230
|
+
code_arguments
|
|
231
|
+
.raw
|
|
232
|
+
.grep(Function)
|
|
233
|
+
.reject { |argument| argument == code_block_argument }
|
|
219
234
|
)
|
|
220
235
|
elsif code_parameter.keyword?
|
|
221
236
|
code_arguments
|
|
@@ -247,17 +262,19 @@ class Code
|
|
|
247
262
|
end
|
|
248
263
|
|
|
249
264
|
code_name = code_parameter.code_name
|
|
250
|
-
|
|
265
|
+
unless code_name.blank?
|
|
266
|
+
code_context.code_set(code_name, code_argument)
|
|
267
|
+
end
|
|
251
268
|
end
|
|
252
269
|
|
|
253
|
-
code_body
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
270
|
+
code_body
|
|
271
|
+
.code_evaluate(
|
|
272
|
+
**globals,
|
|
273
|
+
constructing_literal_classes: constructing_literal_classes,
|
|
274
|
+
context: code_context,
|
|
275
|
+
trusted_evaluation: true
|
|
276
|
+
)
|
|
277
|
+
.tap { persist_instance_functions(code_self) }
|
|
261
278
|
rescue Error::Return => e
|
|
262
279
|
persist_instance_functions(code_self)
|
|
263
280
|
e.code_value
|
|
@@ -318,15 +335,17 @@ class Code
|
|
|
318
335
|
def code_extend(function)
|
|
319
336
|
code_function = function.to_code
|
|
320
337
|
|
|
321
|
-
Function
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
338
|
+
Function
|
|
339
|
+
.new(
|
|
340
|
+
code_function.code_parameters,
|
|
341
|
+
code_function.code_body.raw,
|
|
342
|
+
code_function.definition_context,
|
|
343
|
+
parent: self,
|
|
344
|
+
functions: functions.code_deep_duplicate
|
|
345
|
+
)
|
|
346
|
+
.tap do |extended_function|
|
|
347
|
+
extended_function.instance_functions.code_merge!(instance_functions)
|
|
348
|
+
end
|
|
330
349
|
end
|
|
331
350
|
|
|
332
351
|
def code_deep_duplicate(seen = {})
|
|
@@ -340,7 +359,8 @@ class Code
|
|
|
340
359
|
code_parameters: code_parameters.code_deep_duplicate(seen),
|
|
341
360
|
code_body: code_body.code_deep_duplicate(seen),
|
|
342
361
|
definition_context: definition_context&.code_deep_duplicate(seen),
|
|
343
|
-
parent:
|
|
362
|
+
parent:
|
|
363
|
+
parent.is_a?(Function) ? parent.code_deep_duplicate(seen) : parent,
|
|
344
364
|
functions: functions.code_deep_duplicate(seen),
|
|
345
365
|
instance_functions: instance_functions.code_deep_duplicate(seen),
|
|
346
366
|
documentation: documentation.code_deep_duplicate(seen)
|
|
@@ -381,7 +401,9 @@ class Code
|
|
|
381
401
|
end
|
|
382
402
|
|
|
383
403
|
Object.sorted_dictionary(
|
|
384
|
-
parent_functions.code_merge(
|
|
404
|
+
parent_functions.code_merge(
|
|
405
|
+
function_dictionary_for(instance_functions)
|
|
406
|
+
).raw
|
|
385
407
|
)
|
|
386
408
|
end
|
|
387
409
|
|
|
@@ -440,7 +462,9 @@ class Code
|
|
|
440
462
|
def persist_instance_functions(code_self)
|
|
441
463
|
return unless code_self.is_a?(Object)
|
|
442
464
|
|
|
443
|
-
instance_functions.code_merge!(
|
|
465
|
+
instance_functions.code_merge!(
|
|
466
|
+
documentable_instance_functions(code_self)
|
|
467
|
+
)
|
|
444
468
|
end
|
|
445
469
|
|
|
446
470
|
def documentable_instance_functions(code_self)
|