code-ruby 4.0.0 → 4.0.2

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/bin/code +21 -34
  4. data/lib/code/concerns/shared.rb +103 -99
  5. data/lib/code/format.rb +23 -19
  6. data/lib/code/network.rb +23 -28
  7. data/lib/code/node/call.rb +15 -9
  8. data/lib/code/node/code.rb +5 -5
  9. data/lib/code/node/function.rb +6 -1
  10. data/lib/code/node/left_operation.rb +3 -3
  11. data/lib/code/node/list.rb +10 -8
  12. data/lib/code/node/square_bracket.rb +2 -2
  13. data/lib/code/object/boolean.rb +13 -17
  14. data/lib/code/object/class.rb +33 -27
  15. data/lib/code/object/code.rb +4 -47
  16. data/lib/code/object/context.rb +8 -11
  17. data/lib/code/object/cryptography.rb +12 -6
  18. data/lib/code/object/date.rb +910 -449
  19. data/lib/code/object/decimal.rb +229 -856
  20. data/lib/code/object/dictionary.rb +116 -49
  21. data/lib/code/object/duration.rb +3 -7
  22. data/lib/code/object/function.rb +96 -54
  23. data/lib/code/object/global.rb +122 -209
  24. data/lib/code/object/html.rb +7 -13
  25. data/lib/code/object/http.rb +29 -43
  26. data/lib/code/object/ics.rb +6 -13
  27. data/lib/code/object/identifier_list.rb +16 -11
  28. data/lib/code/object/integer.rb +270 -942
  29. data/lib/code/object/json.rb +8 -28
  30. data/lib/code/object/list.rb +98 -114
  31. data/lib/code/object/nothing.rb +11 -11
  32. data/lib/code/object/number.rb +20 -10
  33. data/lib/code/object/parameter.rb +18 -9
  34. data/lib/code/object/range.rb +62 -108
  35. data/lib/code/object/smtp.rb +20 -15
  36. data/lib/code/object/string.rb +55 -29
  37. data/lib/code/object/super.rb +2 -1
  38. data/lib/code/object/time.rb +1146 -572
  39. data/lib/code/object/url.rb +4 -2
  40. data/lib/code/object.rb +119 -80
  41. data/lib/code/parser.rb +31 -92
  42. data/lib/code.rb +3 -11
  43. metadata +3 -23
@@ -5,7 +5,8 @@ class Code
5
5
  class Number < Object
6
6
  CLASS_DOCUMENTATION = {
7
7
  name: "Number",
8
- description: "represents numeric behavior shared by integers and decimals.",
8
+ description:
9
+ "represents numeric behavior shared by integers and decimals.",
9
10
  examples: [
10
11
  "Number.documentation.name",
11
12
  "Number.instance_functions.keys.include?(:between?)",
@@ -16,7 +17,11 @@ class Code
16
17
  "between?" => {
17
18
  name: "between?",
18
19
  description: "returns whether the number is within inclusive bounds.",
19
- examples: ["2.between?(1, 3)", "1.5.between?(1, 2)", "4.between?(1, 3)"]
20
+ examples: [
21
+ "2.between?(1, 3)",
22
+ "1.5.between?(1, 2)",
23
+ "4.between?(1, 3)"
24
+ ]
20
25
  },
21
26
  "clamp" => {
22
27
  name: "clamp",
@@ -25,38 +30,43 @@ class Code
25
30
  },
26
31
  "divide" => {
27
32
  name: "divide",
28
- description: "returns floor division of the number by another number.",
29
- examples: ["5.divide(2)", "10.divide(3)", "9.5.divide(2)"]
33
+ description:
34
+ "returns floor division of the number by another number.",
35
+ examples: %w[5.divide(2) 10.divide(3) 9.5.divide(2)]
30
36
  },
31
37
  "divide_modulo" => {
32
38
  name: "divide_modulo",
33
39
  description: "returns floor division and modulo as a list.",
34
- examples: ["5.divide_modulo(2)", "10.divide_modulo(3)", "9.5.divide_modulo(2)"]
40
+ examples: %w[
41
+ 5.divide_modulo(2)
42
+ 10.divide_modulo(3)
43
+ 9.5.divide_modulo(2)
44
+ ]
35
45
  },
36
46
  "next" => {
37
47
  name: "next",
38
48
  description: "returns the number plus one.",
39
- examples: ["1.next", "1.5.next", "-1.next"]
49
+ examples: %w[1.next 1.5.next -1.next]
40
50
  },
41
51
  "successor" => {
42
52
  name: "successor",
43
53
  description: "returns the number plus one, matching next.",
44
- examples: ["1.successor", "1.5.successor", "-1.successor"]
54
+ examples: %w[1.successor 1.5.successor -1.successor]
45
55
  },
46
56
  "previous" => {
47
57
  name: "previous",
48
58
  description: "returns the number minus one.",
49
- examples: ["1.previous", "1.5.previous", "-1.previous"]
59
+ examples: %w[1.previous 1.5.previous -1.previous]
50
60
  },
51
61
  "predecessor" => {
52
62
  name: "predecessor",
53
63
  description: "returns the number minus one, matching previous.",
54
- examples: ["1.predecessor", "1.5.predecessor", "-1.predecessor"]
64
+ examples: %w[1.predecessor 1.5.predecessor -1.predecessor]
55
65
  },
56
66
  "remainder" => {
57
67
  name: "remainder",
58
68
  description: "returns the remainder from division by another number.",
59
- examples: ["5.remainder(2)", "10.remainder(3)", "9.5.remainder(2)"]
69
+ examples: %w[5.remainder(2) 10.remainder(3) 9.5.remainder(2)]
60
70
  }
61
71
  }.freeze
62
72
 
@@ -5,7 +5,8 @@ class Code
5
5
  class Parameter < Dictionary
6
6
  CLASS_DOCUMENTATION = {
7
7
  name: "Parameter",
8
- description: "describes one function parameter with its name, kind flags, and default value.",
8
+ description:
9
+ "describes one function parameter with its name, kind flags, and default value.",
9
10
  examples: [
10
11
  "((name) => { name }).parameters.first",
11
12
  "((name:) => { name }).parameters.first.keyword?",
@@ -24,7 +25,8 @@ class Code
24
25
  },
25
26
  "regular?" => {
26
27
  name: "regular?",
27
- description: "returns whether the parameter is not a keyword parameter.",
28
+ description:
29
+ "returns whether the parameter is not a keyword parameter.",
28
30
  examples: [
29
31
  "((name) => { name }).parameters.first.regular?",
30
32
  "((name:) => { name }).parameters.first.regular?",
@@ -33,7 +35,8 @@ class Code
33
35
  },
34
36
  "keyword?" => {
35
37
  name: "keyword?",
36
- description: "returns whether the parameter is a named keyword parameter.",
38
+ description:
39
+ "returns whether the parameter is a named keyword parameter.",
37
40
  examples: [
38
41
  "((name:) => { name }).parameters.first.keyword?",
39
42
  "((name) => { name }).parameters.first.keyword?",
@@ -42,7 +45,8 @@ class Code
42
45
  },
43
46
  "regular_splat?" => {
44
47
  name: "regular_splat?",
45
- description: "returns whether the parameter captures positional arguments with *.",
48
+ description:
49
+ "returns whether the parameter captures positional arguments with *.",
46
50
  examples: [
47
51
  "((...values) => { values }).parameters.first.regular_splat?",
48
52
  "((*values) => { values }).parameters.first.regular_splat?",
@@ -51,7 +55,8 @@ class Code
51
55
  },
52
56
  "keyword_splat?" => {
53
57
  name: "keyword_splat?",
54
- description: "returns whether the parameter captures keyword arguments with **.",
58
+ description:
59
+ "returns whether the parameter captures keyword arguments with **.",
55
60
  examples: [
56
61
  "((**options) => { options }).parameters.first.keyword_splat?",
57
62
  "((name:) => { name }).parameters.first.keyword_splat?",
@@ -60,7 +65,8 @@ class Code
60
65
  },
61
66
  "block?" => {
62
67
  name: "block?",
63
- description: "returns whether the parameter captures one function argument with &.",
68
+ description:
69
+ "returns whether the parameter captures one function argument with &.",
64
70
  examples: [
65
71
  "((&block) => { block }).parameters.first.block?",
66
72
  "((name) => { name }).parameters.first.block?",
@@ -69,7 +75,8 @@ class Code
69
75
  },
70
76
  "blocks?" => {
71
77
  name: "blocks?",
72
- description: "returns whether the parameter captures remaining function arguments with &&.",
78
+ description:
79
+ "returns whether the parameter captures remaining function arguments with &&.",
73
80
  examples: [
74
81
  "((&&blocks) => { blocks }).parameters.first.blocks?",
75
82
  "((&block) => { block }).parameters.first.blocks?",
@@ -78,7 +85,8 @@ class Code
78
85
  },
79
86
  "spread?" => {
80
87
  name: "spread?",
81
- description: "returns whether the parameter captures every provided argument with spread syntax.",
88
+ description:
89
+ "returns whether the parameter captures every provided argument with spread syntax.",
82
90
  examples: [
83
91
  "((...values) => { values }).parameters.first.spread?",
84
92
  "((name) => { name }).parameters.first.spread?",
@@ -105,7 +113,8 @@ class Code
105
113
  },
106
114
  "default" => {
107
115
  name: "default",
108
- description: "returns the default value for the parameter, or nothing when none is set.",
116
+ description:
117
+ "returns the default value for the parameter, or nothing when none is set.",
109
118
  examples: [
110
119
  "((name = :a) => { name }).parameters.first.default",
111
120
  "((name) => { name }).parameters.first.default",
@@ -5,17 +5,15 @@ class Code
5
5
  class Range < Object
6
6
  CLASS_DOCUMENTATION = {
7
7
  name: "Range",
8
- description: "represents inclusive or exclusive sequences between comparable bounds.",
9
- examples: [
10
- "1..3",
11
- "1...3",
12
- "(1..3).to_list"
13
- ]
8
+ description:
9
+ "represents inclusive or exclusive sequences between comparable bounds.",
10
+ examples: %w[1..3 1...3 (1..3).to_list]
14
11
  }.freeze
15
12
  INSTANCE_FUNCTIONS = {
16
13
  "all?" => {
17
14
  name: "all?",
18
- description: "returns whether every item in the range matches a function.",
15
+ description:
16
+ "returns whether every item in the range matches a function.",
19
17
  examples: [
20
18
  "(1..3).all?((x) => { x > 0 })",
21
19
  "(1..3).all?((x) => { x < 4 })",
@@ -24,7 +22,8 @@ class Code
24
22
  },
25
23
  "any?" => {
26
24
  name: "any?",
27
- description: "returns whether any item in the range matches a function.",
25
+ description:
26
+ "returns whether any item in the range matches a function.",
28
27
  examples: [
29
28
  "(1..3).any?((x) => { x == 2 })",
30
29
  "(1..3).any?((x) => { x == 1 })",
@@ -33,7 +32,8 @@ class Code
33
32
  },
34
33
  "none?" => {
35
34
  name: "none?",
36
- description: "returns whether no items in the range match a function.",
35
+ description:
36
+ "returns whether no items in the range match a function.",
37
37
  examples: [
38
38
  "(1..3).none?((x) => { x > 3 })",
39
39
  "(1..3).none?((x) => { x == 2 })",
@@ -42,7 +42,8 @@ class Code
42
42
  },
43
43
  "each" => {
44
44
  name: "each",
45
- description: "calls a function for each item in the range and returns the range.",
45
+ description:
46
+ "calls a function for each item in the range and returns the range.",
46
47
  examples: [
47
48
  "(1..3).each((x) => { x })",
48
49
  "(:a..:c).each((x) => { x })",
@@ -51,7 +52,8 @@ class Code
51
52
  },
52
53
  "reverse_each" => {
53
54
  name: "reverse_each",
54
- description: "calls a function for each item in the range in reverse order.",
55
+ description:
56
+ "calls a function for each item in the range in reverse order.",
55
57
  examples: [
56
58
  "(1..3).reverse_each((x) => { x })",
57
59
  "(:a..:c).reverse_each((x) => { x })",
@@ -61,123 +63,88 @@ class Code
61
63
  "include?" => {
62
64
  name: "include?",
63
65
  description: "returns whether the range includes a value.",
64
- examples: [
65
- "(1..3).include?(2)",
66
- "(1..3).include?(4)",
67
- "(:a..:c).include?(:b)"
66
+ examples: %w[
67
+ (1..3).include?(2)
68
+ (1..3).include?(4)
69
+ (:a..:c).include?(:b)
68
70
  ]
69
71
  },
70
72
  "member?" => {
71
73
  name: "member?",
72
74
  description: "returns whether the range includes a value.",
73
- examples: [
74
- "(1..3).member?(2)",
75
- "(1..3).member?(4)",
76
- "(:a..:c).member?(:b)"
77
- ]
75
+ examples: %w[(1..3).member?(2) (1..3).member?(4) (:a..:c).member?(:b)]
78
76
  },
79
77
  "cover?" => {
80
78
  name: "cover?",
81
79
  description: "returns whether a value is between the range bounds.",
82
- examples: [
83
- "(1..3).cover?(2)",
84
- "(1..3).cover?(4)",
85
- "(:a..:c).cover?(:b)"
86
- ]
80
+ examples: %w[(1..3).cover?(2) (1..3).cover?(4) (:a..:c).cover?(:b)]
87
81
  },
88
82
  "overlap?" => {
89
83
  name: "overlap?",
90
84
  description: "returns whether the range overlaps another range.",
91
- examples: [
92
- "(1..3).overlap?(2..4)",
93
- "(1..3).overlap?(4..6)",
94
- "(:a..:c).overlap?(:b..:d)"
85
+ examples: %w[
86
+ (1..3).overlap?(2..4)
87
+ (1..3).overlap?(4..6)
88
+ (:a..:c).overlap?(:b..:d)
95
89
  ]
96
90
  },
97
91
  "empty?" => {
98
92
  name: "empty?",
99
93
  description: "returns whether the range is empty.",
100
- examples: [
101
- "(1..3).empty?",
102
- "(1...1).empty?",
103
- "(:a..:c).empty?"
104
- ]
94
+ examples: %w[(1..3).empty? (1...1).empty? (:a..:c).empty?]
105
95
  },
106
96
  "begin" => {
107
97
  name: "begin",
108
98
  description: "returns the starting bound of the range.",
109
- examples: [
110
- "(1..3).begin",
111
- "(:a..:c).begin",
112
- "(1...3).begin"
113
- ]
99
+ examples: %w[(1..3).begin (:a..:c).begin (1...3).begin]
114
100
  },
115
101
  "end" => {
116
102
  name: "end",
117
103
  description: "returns the ending bound of the range.",
118
- examples: [
119
- "(1..3).end",
120
- "(:a..:c).end",
121
- "(1...3).end"
122
- ]
104
+ examples: %w[(1..3).end (:a..:c).end (1...3).end]
123
105
  },
124
106
  "exclude_end?" => {
125
107
  name: "exclude_end?",
126
108
  description: "returns whether the range excludes its ending bound.",
127
- examples: [
128
- "(1..3).exclude_end?",
129
- "(1...3).exclude_end?",
130
- "(:a...:c).exclude_end?"
109
+ examples: %w[
110
+ (1..3).exclude_end?
111
+ (1...3).exclude_end?
112
+ (:a...:c).exclude_end?
131
113
  ]
132
114
  },
133
115
  "first" => {
134
116
  name: "first",
135
117
  description: "returns the first item in the range.",
136
- examples: [
137
- "(1..3).first",
138
- "(2..4).first",
139
- "(:a..:c).first"
140
- ]
118
+ examples: %w[(1..3).first (2..4).first (:a..:c).first]
141
119
  },
142
120
  "last" => {
143
121
  name: "last",
144
122
  description: "returns the last item in the range.",
145
- examples: [
146
- "(1..3).last",
147
- "(2..4).last",
148
- "(:a..:c).last"
149
- ]
123
+ examples: %w[(1..3).last (2..4).last (:a..:c).last]
150
124
  },
151
125
  "minimum" => {
152
126
  name: "minimum",
153
127
  description: "returns the minimum item in the range.",
154
- examples: [
155
- "(1..3).minimum",
156
- "(:a..:c).minimum",
157
- "(3..1).minimum"
158
- ]
128
+ examples: %w[(1..3).minimum (:a..:c).minimum (3..1).minimum]
159
129
  },
160
130
  "maximum" => {
161
131
  name: "maximum",
162
132
  description: "returns the maximum item in the range.",
163
- examples: [
164
- "(1..3).maximum",
165
- "(:a..:c).maximum",
166
- "(3..1).maximum"
167
- ]
133
+ examples: %w[(1..3).maximum (:a..:c).maximum (3..1).maximum]
168
134
  },
169
135
  "minimum_maximum" => {
170
136
  name: "minimum_maximum",
171
137
  description: "returns the minimum and maximum items as a list.",
172
- examples: [
173
- "(1..3).minimum_maximum",
174
- "(:a..:c).minimum_maximum",
175
- "(3..1).minimum_maximum"
138
+ examples: %w[
139
+ (1..3).minimum_maximum
140
+ (:a..:c).minimum_maximum
141
+ (3..1).minimum_maximum
176
142
  ]
177
143
  },
178
144
  "map" => {
179
145
  name: "map",
180
- description: "returns a list with each item transformed by a function.",
146
+ description:
147
+ "returns a list with each item transformed by a function.",
181
148
  examples: [
182
149
  "(1..3).map((x) => { x + 1 })",
183
150
  "(1..3).map((x) => { x.to_string })",
@@ -214,11 +181,7 @@ class Code
214
181
  "step" => {
215
182
  name: "step",
216
183
  description: "returns a list of items separated by a step size.",
217
- examples: [
218
- "(1..5).step(2)",
219
- "(1..5).step(1)",
220
- "(1...5).step(2)"
221
- ]
184
+ examples: %w[(1..5).step(2) (1..5).step(1) (1...5).step(2)]
222
185
  },
223
186
  "binary_search" => {
224
187
  name: "binary_search",
@@ -232,24 +195,17 @@ class Code
232
195
  "sample" => {
233
196
  name: "sample",
234
197
  description: "returns a random item from the range.",
235
- examples: [
236
- "(1..3).sample",
237
- "(2..4).sample",
238
- "(:a..:c).sample"
239
- ]
198
+ examples: %w[(1..3).sample (2..4).sample (:a..:c).sample]
240
199
  },
241
200
  "size" => {
242
201
  name: "size",
243
202
  description: "returns the number of items in the range.",
244
- examples: [
245
- "(1..3).size",
246
- "(1...3).size",
247
- "(:a..:c).size"
248
- ]
203
+ examples: %w[(1..3).size (1...3).size (:a..:c).size]
249
204
  },
250
205
  "count" => {
251
206
  name: "count",
252
- description: "returns the number of items, optionally matched by a function.",
207
+ description:
208
+ "returns the number of items, optionally matched by a function.",
253
209
  examples: [
254
210
  "(1..3).count",
255
211
  "(1...3).count",
@@ -259,28 +215,20 @@ class Code
259
215
  "to_list" => {
260
216
  name: "to_list",
261
217
  description: "returns the range items as a list.",
262
- examples: [
263
- "(1..3).to_list",
264
- "(1...3).to_list",
265
- "(:a..:c).to_list"
266
- ]
218
+ examples: %w[(1..3).to_list (1...3).to_list (:a..:c).to_list]
267
219
  },
268
220
  "entries" => {
269
221
  name: "entries",
270
222
  description: "returns the range items as a list.",
271
- examples: [
272
- "(1..3).entries",
273
- "(1...3).entries",
274
- "(:a..:c).entries"
275
- ]
223
+ examples: %w[(1..3).entries (1...3).entries (:a..:c).entries]
276
224
  },
277
225
  "to_dictionary" => {
278
226
  name: "to_dictionary",
279
227
  description: "returns a dictionary built from indexed range items.",
280
- examples: [
281
- "(1..3).to_dictionary",
282
- "(1...3).to_dictionary",
283
- "(:a..:c).to_dictionary"
228
+ examples: %w[
229
+ (1..3).to_dictionary
230
+ (1...3).to_dictionary
231
+ (:a..:c).to_dictionary
284
232
  ]
285
233
  }
286
234
  }.freeze
@@ -707,9 +655,17 @@ class Code
707
655
  loop do
708
656
  comparison =
709
657
  if step_is_positive
710
- exclude_end? ? code_element.code_less(code_right) : code_element.code_less_or_equal(code_right)
658
+ if exclude_end?
659
+ code_element.code_less(code_right)
660
+ else
661
+ code_element.code_less_or_equal(code_right)
662
+ end
711
663
  else
712
- exclude_end? ? code_element.code_greater(code_right) : code_element.code_greater_or_equal(code_right)
664
+ if exclude_end?
665
+ code_element.code_greater(code_right)
666
+ else
667
+ code_element.code_greater_or_equal(code_right)
668
+ end
713
669
  end
714
670
 
715
671
  break unless comparison.truthy?
@@ -755,9 +711,7 @@ class Code
755
711
  def code_count(argument = nil, **globals)
756
712
  code_argument = argument.to_code
757
713
 
758
- if code_argument.nothing?
759
- return Integer.new(raw.to_a.size)
760
- end
714
+ return Integer.new(raw.to_a.size) if code_argument.nothing?
761
715
 
762
716
  index = 0
763
717
  Integer.new(
@@ -6,20 +6,16 @@ class Code
6
6
  CLASS_DOCUMENTATION = {
7
7
  name: "Smtp",
8
8
  description: "stores smtp settings and sends email messages.",
9
- examples: [
10
- "Smtp",
11
- "Smtp.new",
12
- "Smtp.new.functions.keys.include?(:send)"
13
- ]
9
+ examples: %w[Smtp Smtp.new Smtp.new.functions.keys.include?(:send)]
14
10
  }.freeze
15
11
  INSTANCE_FUNCTIONS = {
16
12
  "send" => {
17
13
  name: "send",
18
14
  description: "sends an email using the receiver's smtp settings.",
19
- examples: [
20
- "Smtp.new.respond_to?(:send)",
21
- "Smtp.new.functions.keys.include?(:send)",
22
- "Smtp.new.instance_functions.keys.include?(:send)"
15
+ examples: %w[
16
+ Smtp.new.respond_to?(:send)
17
+ Smtp.new.functions.keys.include?(:send)
18
+ Smtp.new.instance_functions.keys.include?(:send)
23
19
  ]
24
20
  }
25
21
  }.freeze
@@ -108,9 +104,6 @@ class Code
108
104
 
109
105
  resolved_ip = validate_delivery_target!(address, port)
110
106
 
111
- encoded_message = mail.encoded
112
- ::Code.ensure_input_size!(encoded_message, label: "smtp message")
113
-
114
107
  deliver_mail(
115
108
  mail,
116
109
  address: address,
@@ -127,14 +120,23 @@ class Code
127
120
  private
128
121
 
129
122
  def validate_delivery_target!(address, port)
130
- resolved_ip = ::Code::Network.validate_public_host!(address, service: "smtp").first
123
+ resolved_ip =
124
+ ::Code::Network.validate_public_host!(address, service: "smtp").first
131
125
 
132
126
  return resolved_ip if ALLOWED_PORTS.include?(port)
133
127
 
134
128
  raise Error, "smtp: unsupported port"
135
129
  end
136
130
 
137
- def deliver_mail(mail, address:, resolved_ip:, port:, user_name:, password:, authentication:)
131
+ def deliver_mail(
132
+ mail,
133
+ address:,
134
+ resolved_ip:,
135
+ port:,
136
+ user_name:,
137
+ password:,
138
+ authentication:
139
+ )
138
140
  envelope = Mail::SmtpEnvelope.new(mail)
139
141
  smtp =
140
142
  Net::SMTP.new(
@@ -161,7 +163,10 @@ class Code
161
163
  end
162
164
  rescue Timeout::Error
163
165
  raise Error, "smtp timeout"
164
- rescue OpenSSL::SSL::SSLError, IOError, SystemCallError, SocketError,
166
+ rescue OpenSSL::SSL::SSLError,
167
+ IOError,
168
+ SystemCallError,
169
+ SocketError,
165
170
  Net::SMTPError
166
171
  raise Error, "smtp error"
167
172
  end