code-ruby 1.3.0 → 1.5.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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.node-version +1 -1
  3. data/.npm-version +1 -1
  4. data/.rubocop.yml +8 -7
  5. data/.ruby-version +1 -1
  6. data/.tool-versions +2 -2
  7. data/Gemfile +1 -1
  8. data/Gemfile.lock +81 -65
  9. data/VERSION +1 -1
  10. data/bin/code +14 -7
  11. data/code-ruby.gemspec +2 -2
  12. data/lib/code/concerns/shared.rb +17 -61
  13. data/lib/code/concerns.rb +2 -0
  14. data/lib/code/node/code.rb +10 -0
  15. data/lib/code/node/dictionary.rb +34 -15
  16. data/lib/code/node/function_parameter.rb +1 -1
  17. data/lib/code/object/boolean.rb +2 -2
  18. data/lib/code/object/class.rb +2 -2
  19. data/lib/code/object/code.rb +8 -2
  20. data/lib/code/object/context.rb +1 -1
  21. data/lib/code/object/date.rb +3 -3
  22. data/lib/code/object/decimal.rb +3 -3
  23. data/lib/code/object/dictionary.rb +23 -7
  24. data/lib/code/object/duration.rb +3 -3
  25. data/lib/code/object/function.rb +2 -2
  26. data/lib/code/object/global.rb +7 -6
  27. data/lib/code/object/html.rb +4 -5
  28. data/lib/code/object/http.rb +0 -2
  29. data/lib/code/object/integer.rb +3 -3
  30. data/lib/code/object/list.rb +10 -3
  31. data/lib/code/object/nothing.rb +2 -2
  32. data/lib/code/object/parameter.rb +2 -2
  33. data/lib/code/object/range.rb +2 -2
  34. data/lib/code/object/string.rb +13 -12
  35. data/lib/code/object/time.rb +2 -6
  36. data/lib/code/object.rb +2 -6
  37. data/lib/code/parser/call.rb +11 -5
  38. data/lib/code/parser/class.rb +1 -34
  39. data/lib/code/parser/dictionary.rb +7 -5
  40. data/lib/code/parser/equal.rb +0 -4
  41. data/lib/code/parser/function.rb +24 -2
  42. data/lib/code/parser/group.rb +32 -2
  43. data/lib/code/parser/if.rb +31 -4
  44. data/lib/code/parser/name.rb +7 -2
  45. data/lib/code/parser/while.rb +32 -1
  46. data/lib/code/type/sig.rb +2 -2
  47. data/lib/code/type.rb +1 -1
  48. data/lib/code.rb +25 -18
  49. data/package-lock.json +2 -2
  50. data/package.json +2 -2
  51. data/spec/code/object/http_spec.rb +70 -66
  52. data/spec/code_spec.rb +6 -2
  53. metadata +4 -6
  54. data/TODO +0 -219
  55. data/bin/console +0 -6
@@ -3,10 +3,10 @@
3
3
  class Code
4
4
  class Object
5
5
  class Date < Object
6
- def initialize(*args, **_kargs, &)
7
- @raw = ::Date.parse(args.map(&:to_s).join("-"))
6
+ def initialize(*args, **_kargs, &_block)
7
+ self.raw = ::Date.parse(args.map(&:to_s).join("-"))
8
8
  rescue ::Date::Error
9
- @raw = ::Date.current
9
+ self.raw = ::Date.current
10
10
  end
11
11
 
12
12
  def self.call(**args)
@@ -3,8 +3,8 @@
3
3
  class Code
4
4
  class Object
5
5
  class Decimal < Object
6
- def initialize(*args, **_kargs, &)
7
- @raw =
6
+ def initialize(*args, **_kargs, &_block)
7
+ self.raw =
8
8
  if args.first.class.in?(NUMBER_CLASSES)
9
9
  if args.second.class.in?(NUMBER_CLASSES)
10
10
  args.first.to_s.to_d * (10**args.second.to_s.to_d)
@@ -15,7 +15,7 @@ class Code
15
15
  0.to_d
16
16
  end
17
17
  rescue FloatDomainError
18
- @raw = 0.to_d
18
+ self.raw = 0.to_d
19
19
  end
20
20
 
21
21
  def call(**args)
@@ -15,8 +15,8 @@ class Code
15
15
  delegate :code_two?, to: :code_size
16
16
  delegate :code_zero?, to: :code_size
17
17
 
18
- def initialize(*args, **kargs, &)
19
- @raw =
18
+ def initialize(*args, **kargs, &_block)
19
+ self.raw =
20
20
  args
21
21
  .map do |arg|
22
22
  if arg.is_an?(::Hash)
@@ -218,7 +218,7 @@ class Code
218
218
  end
219
219
 
220
220
  def code_clear
221
- @raw = {}
221
+ self.raw = {}
222
222
  self
223
223
  end
224
224
 
@@ -265,11 +265,19 @@ class Code
265
265
  .map
266
266
  .with_index do |code_argument, index|
267
267
  if code_default.nothing?
268
- [code_argument, code_delete(code_argument, index:, **globals)]
268
+ [
269
+ code_argument,
270
+ code_delete(code_argument, index: index, **globals)
271
+ ]
269
272
  else
270
273
  [
271
274
  code_argument,
272
- code_delete(code_argument, code_default, index:, **globals)
275
+ code_delete(
276
+ code_argument,
277
+ code_default,
278
+ index: index,
279
+ **globals
280
+ )
273
281
  ]
274
282
  end
275
283
  end
@@ -378,11 +386,19 @@ class Code
378
386
  .map
379
387
  .with_index do |code_argument, index|
380
388
  if code_default.nothing?
381
- [code_argument, code_fetch(code_argument, index:, **globals)]
389
+ [
390
+ code_argument,
391
+ code_fetch(code_argument, index: index, **globals)
392
+ ]
382
393
  else
383
394
  [
384
395
  code_argument,
385
- code_fetch(code_argument, code_default, index:, **globals)
396
+ code_fetch(
397
+ code_argument,
398
+ code_default,
399
+ index: index,
400
+ **globals
401
+ )
386
402
  ]
387
403
  end
388
404
  end
@@ -3,8 +3,8 @@
3
3
  class Code
4
4
  class Object
5
5
  class Duration < Object
6
- def initialize(*args, **_kargs, &)
7
- @raw =
6
+ def initialize(*args, **_kargs, &_block)
7
+ self.raw =
8
8
  if args.first.is_an?(::ActiveSupport::Duration)
9
9
  args.first
10
10
  elsif args.first.is_a?(Duration)
@@ -13,7 +13,7 @@ class Code
13
13
  ::ActiveSupport::Duration.parse(args.first.to_s)
14
14
  end
15
15
  rescue ::ActiveSupport::Duration::ISO8601Parser::ParsingError
16
- @raw = 0.seconds
16
+ self.raw = 0.seconds
17
17
  end
18
18
 
19
19
  def call(**args)
@@ -5,7 +5,7 @@ class Code
5
5
  class Function < Object
6
6
  attr_reader :code_parameters, :code_body
7
7
 
8
- def initialize(*args, **_kargs, &)
8
+ def initialize(*args, **_kargs, &_block)
9
9
  @code_parameters =
10
10
  List
11
11
  .new(args.first)
@@ -15,7 +15,7 @@ class Code
15
15
 
16
16
  @code_body = Code.new(args.second.presence)
17
17
 
18
- @raw = List.new([code_parameters, code_body])
18
+ self.raw = List.new([code_parameters, code_body])
19
19
  end
20
20
 
21
21
  def call(**args)
@@ -7,8 +7,10 @@ class Code
7
7
  code_operator = args.fetch(:operator, nil).to_code
8
8
  code_arguments = args.fetch(:arguments, []).to_code
9
9
  output = args.fetch(:output)
10
+ input = args.fetch(:input)
10
11
  code_context = args.fetch(:context).to_code
11
12
  code_value = code_arguments.code_first
13
+ globals = multi_fetch(args, *GLOBALS)
12
14
 
13
15
  case code_operator.to_s
14
16
  when "Boolean"
@@ -105,11 +107,7 @@ class Code
105
107
  end
106
108
  when "Time"
107
109
  sig(args) { Object.repeat }
108
- if code_arguments.any?
109
- Time.zone.local(*code_arguments.raw)
110
- else
111
- Class.new(Time)
112
- end
110
+ code_arguments.any? ? Time.new(*code_arguments.raw) : Class.new(Time)
113
111
  when "Context"
114
112
  sig(args) { Object.repeat }
115
113
  if code_arguments.any?
@@ -145,7 +143,7 @@ class Code
145
143
  code_arguments.any? ? Json.new(*code_arguments.raw) : Class.new(Json)
146
144
  when "evaluate"
147
145
  sig(args) { Object }
148
- Code.evaluate(code_value.to_s)
146
+ Code.code_evaluate(code_value.code_to_string, **globals)
149
147
  when "p"
150
148
  sig(args) { Object.repeat }
151
149
  output.puts(*code_arguments.raw.map(&:inspect))
@@ -154,6 +152,9 @@ class Code
154
152
  sig(args) { Object.repeat }
155
153
  output.print(*code_arguments.raw)
156
154
  Nothing.new
155
+ when "read"
156
+ sig(args) { Object.repeat }
157
+ input.gets.to_code
157
158
  when "puts"
158
159
  sig(args) { Object.repeat }
159
160
  output.puts(*code_arguments.raw)
@@ -3,13 +3,12 @@
3
3
  class Code
4
4
  class Object
5
5
  class Html < Object
6
- def initialize(*args, **_kargs, &)
7
- @raw =
6
+ def initialize(*args, **_kargs, &_block)
7
+ self.raw =
8
8
  if args.first.is_an?(Html)
9
9
  args.first.raw
10
- elsif args.first.is_a?(::Nokogiri::XML::NodeSet)
11
- args.first
12
- elsif args.first.is_a?(Nokogiri::XML::Node)
10
+ elsif args.first.is_a?(::Nokogiri::XML::NodeSet) ||
11
+ args.first.is_a?(Nokogiri::XML::Node)
13
12
  args.first
14
13
  else
15
14
  Nokogiri.HTML(args.first.to_s)
@@ -175,8 +175,6 @@ class Code
175
175
 
176
176
  request_class =
177
177
  case verb
178
- when "get"
179
- ::Net::HTTP::Get
180
178
  when "head"
181
179
  ::Net::HTTP::Head
182
180
  when "post"
@@ -3,8 +3,8 @@
3
3
  class Code
4
4
  class Object
5
5
  class Integer < Object
6
- def initialize(*args, **_kargs, &)
7
- @raw =
6
+ def initialize(*args, **_kargs, &_block)
7
+ self.raw =
8
8
  if args.first.class.in?(NUMBER_CLASSES)
9
9
  if args.second.class.in?(NUMBER_CLASSES)
10
10
  (args.first.to_s.to_d * (10**args.second.to_s.to_d)).to_i
@@ -15,7 +15,7 @@ class Code
15
15
  0
16
16
  end
17
17
  rescue FloatDomainError
18
- @raw = 0
18
+ self.raw = 0
19
19
  end
20
20
 
21
21
  def call(**args)
@@ -3,8 +3,8 @@
3
3
  class Code
4
4
  class Object
5
5
  class List < Object
6
- def initialize(*args, **_kargs, &)
7
- @raw =
6
+ def initialize(*args, **_kargs, &_block)
7
+ self.raw =
8
8
  if args.first.is_a?(List)
9
9
  args.first.raw.map(&:to_code)
10
10
  elsif args.first.is_an?(::Array)
@@ -45,6 +45,9 @@ class Code
45
45
  when "sample"
46
46
  sig(args) { Integer.maybe }
47
47
  code_sample(code_value)
48
+ when "shuffle"
49
+ sig(args)
50
+ code_shuffle
48
51
  when "flatten"
49
52
  sig(args) { Integer.maybe }
50
53
  code_flatten
@@ -187,6 +190,10 @@ class Code
187
190
  end
188
191
  end
189
192
 
193
+ def code_shuffle
194
+ List.new(raw.shuffle)
195
+ end
196
+
190
197
  def code_flatten(level = nil)
191
198
  code_level = level.to_code
192
199
  code_level = Integer.new(-1) if code_level.nothing?
@@ -437,7 +444,7 @@ class Code
437
444
  end
438
445
 
439
446
  def code_deep_duplicate
440
- List.new(raw.dup.map { |element| element.code_deep_duplicate })
447
+ List.new(raw.dup.map(&:code_deep_duplicate))
441
448
  end
442
449
 
443
450
  def code_get(argument)
@@ -3,8 +3,8 @@
3
3
  class Code
4
4
  class Object
5
5
  class Nothing < Object
6
- def initialize(*_args, **_kargs, &)
7
- @raw = nil
6
+ def initialize(*_args, **_kargs, &_block)
7
+ self.raw = nil
8
8
  end
9
9
 
10
10
  def truthy?
@@ -3,8 +3,8 @@
3
3
  class Code
4
4
  class Object
5
5
  class Parameter < Object
6
- def initialize(*args, **_kargs, &)
7
- @raw = Dictionary.new(args.first)
6
+ def initialize(*args, **_kargs, &_block)
7
+ self.raw = Dictionary.new(args.first)
8
8
  end
9
9
 
10
10
  def code_name
@@ -5,7 +5,7 @@ class Code
5
5
  class Range < Object
6
6
  attr_reader :code_left, :code_right, :code_options, :code_exclude_end
7
7
 
8
- def initialize(*args, **kargs, &)
8
+ def initialize(*args, **kargs, &_block)
9
9
  if args.first.is_a?(Range)
10
10
  @code_left = args.first.code_left
11
11
  @code_right = args.first.code_right
@@ -26,7 +26,7 @@ class Code
26
26
  @code_exclude_end = Boolean.new(code_options.code_get(:exclude_end))
27
27
  end
28
28
 
29
- @raw = ::Range.new(code_left, code_right, exclude_end?)
29
+ self.raw = ::Range.new(code_left, code_right, exclude_end?)
30
30
  end
31
31
 
32
32
  def call(**args)
@@ -3,18 +3,19 @@
3
3
  class Code
4
4
  class Object
5
5
  class String < Object
6
- def initialize(*args, **_kargs, &)
7
- if args.first.is_an?(Class)
8
- @raw = args.first.raw.name
9
- elsif args.first.is_an?(Object)
10
- @raw = args.first.raw.to_s
11
- elsif args.first.is_a?(::Class)
12
- @raw = args.first.name
13
- elsif args.first
14
- @raw = args.first.to_s
15
- else
16
- @raw = ""
17
- end
6
+ def initialize(*args, **_kargs, &_block)
7
+ self.raw =
8
+ if args.first.is_an?(Class)
9
+ args.first.raw.name
10
+ elsif args.first.is_an?(Object)
11
+ args.first.raw.to_s
12
+ elsif args.first.is_a?(::Class)
13
+ args.first.name
14
+ elsif args.first
15
+ args.first.to_s
16
+ else
17
+ ""
18
+ end
18
19
  end
19
20
 
20
21
  def call(**args)
@@ -5,9 +5,9 @@ class Code
5
5
  class Time < Object
6
6
  DEFAULT_ZONE = "Etc/UTC"
7
7
 
8
- def initialize(*args, **_kargs, &)
8
+ def initialize(*args, **_kargs, &_block)
9
9
  ::Time.zone ||= DEFAULT_ZONE
10
- @raw = ::Time.zone.parse(args.first.to_s) || ::Time.zone.now
10
+ self.raw = ::Time.zone.parse(args.first.to_s) || ::Time.zone.now
11
11
  end
12
12
 
13
13
  def self.call(**args)
@@ -79,10 +79,6 @@ class Code
79
79
  end
80
80
  end
81
81
 
82
- def self.code_hour
83
- code_now.code_hour
84
- end
85
-
86
82
  def self.code_tomorrow
87
83
  ::Time.zone ||= DEFAULT_ZONE
88
84
  new(::Time.zone.tomorrow)
data/lib/code/object.rb CHANGED
@@ -23,17 +23,13 @@ class Code
23
23
  end
24
24
 
25
25
  def self.repeat(minimum = 0, maximum = nil)
26
- Type::Repeat.new(self, minimum:, maximum:)
26
+ Type::Repeat.new(self, minimum: minimum, maximum: maximum)
27
27
  end
28
28
 
29
29
  def self.|(other)
30
30
  Type::Or.new(self, other)
31
31
  end
32
32
 
33
- def self.name
34
- super.split("::")[2..].join("::")
35
- end
36
-
37
33
  def self.code_new(*args)
38
34
  new(*args)
39
35
  end
@@ -43,7 +39,7 @@ class Code
43
39
  end
44
40
 
45
41
  def code_new(*args)
46
- self.class.code_new(**args)
42
+ self.class.code_new(*args)
47
43
  end
48
44
  end
49
45
  end
@@ -59,6 +59,10 @@ class Code
59
59
  str("do")
60
60
  end
61
61
 
62
+ def begin_keyword
63
+ str("do")
64
+ end
65
+
62
66
  def end_keyword
63
67
  str("end")
64
68
  end
@@ -107,13 +111,15 @@ class Code
107
111
 
108
112
  def block
109
113
  (
110
- do_keyword << whitespace? << parameters.aka(:parameters).maybe <<
111
- code.aka(:body) << end_keyword.maybe
114
+ (do_keyword | begin_keyword).ignore << whitespace <<
115
+ parameters.aka(:parameters).maybe << whitespace? <<
116
+ code.aka(:body) << (whitespace? << end_keyword).maybe.ignore
112
117
  ) |
113
118
  (
114
- opening_curly_bracket << whitespace? <<
115
- parameters.aka(:parameters).maybe << code.aka(:body) <<
116
- closing_curly_bracket.maybe
119
+ opening_curly_bracket.ignore << whitespace? <<
120
+ parameters.aka(:parameters).maybe << whitespace? <<
121
+ code.aka(:body) <<
122
+ (whitespace? << closing_curly_bracket).maybe.ignore
117
123
  )
118
124
  end
119
125
 
@@ -7,41 +7,8 @@ class Code
7
7
  While
8
8
  end
9
9
 
10
- def name
11
- Name
12
- end
13
-
14
- def code
15
- Code
16
- end
17
-
18
- def whitespace
19
- Whitespace
20
- end
21
-
22
- def whitespace?
23
- whitespace.maybe
24
- end
25
-
26
- def class_keyword
27
- str("class")
28
- end
29
-
30
- def end_keyword
31
- str("end")
32
- end
33
-
34
- def lesser
35
- str("<")
36
- end
37
-
38
10
  def root
39
- (
40
- class_keyword << whitespace? << name.aka(:name) <<
41
- (
42
- whitespace? << lesser << whitespace? << name.aka(:superclass)
43
- ).maybe << code.aka(:body) << end_keyword.maybe
44
- ).aka(:class) | statement
11
+ statement
45
12
  end
46
13
  end
47
14
  end
@@ -48,14 +48,16 @@ class Code
48
48
  end
49
49
 
50
50
  def key_value
51
- (name.aka(:name) << colon << code_present.aka(:value).maybe) |
51
+ (name.aka(:name) << colon << code_present.aka(:code).maybe).aka(
52
+ :name_code
53
+ ) |
52
54
  (
53
- statement.aka(:statement) << colon << code_present.aka(:value).maybe
54
- ) |
55
+ statement.aka(:statement) << colon << code_present.aka(:code).maybe
56
+ ).aka(:statement_code) |
55
57
  (
56
58
  statement.aka(:statement) << whitespace? << equal << greater <<
57
- code_present.aka(:value).maybe
58
- ) | statement.aka(:statement)
59
+ code_present.aka(:code).maybe
60
+ ).aka(:statement_code) | code_present.aka(:code)
59
61
  end
60
62
 
61
63
  def root
@@ -51,10 +51,6 @@ class Code
51
51
  str("^")
52
52
  end
53
53
 
54
- def dot
55
- str(".")
56
- end
57
-
58
54
  def right_statement
59
55
  OrKeyword
60
56
  end
@@ -23,6 +23,18 @@ class Code
23
23
  whitespace.maybe
24
24
  end
25
25
 
26
+ def do_keyword
27
+ str("do")
28
+ end
29
+
30
+ def begin_keyword
31
+ str("begin")
32
+ end
33
+
34
+ def end_keyword
35
+ str("end")
36
+ end
37
+
26
38
  def opening_parenthesis
27
39
  str("(")
28
40
  end
@@ -88,11 +100,21 @@ class Code
88
100
  (whitespace? << closing_parenthesis.ignore).maybe
89
101
  end
90
102
 
103
+ def body
104
+ (
105
+ (begin_keyword | do_keyword).ignore << whitespace << code <<
106
+ (whitespace? << end_keyword).maybe.ignore
107
+ ) |
108
+ (
109
+ opening_curly_bracket.ignore << whitespace? << code <<
110
+ (whitespace? << closing_curly_bracket).maybe.ignore
111
+ ) | (code << (whitespace? << end_keyword).maybe.ignore)
112
+ end
113
+
91
114
  def root
92
115
  (
93
116
  parameters.aka(:parameters) << whitespace? << equal << greater <<
94
- whitespace? << opening_curly_bracket << code.aka(:body) <<
95
- closing_curly_bracket.maybe
117
+ whitespace? << body.aka(:body)
96
118
  ).aka(:function) | Dictionary
97
119
  end
98
120
  end
@@ -7,6 +7,14 @@ class Code
7
7
  Code
8
8
  end
9
9
 
10
+ def whitespace
11
+ Whitespace
12
+ end
13
+
14
+ def whitespace?
15
+ whitespace.maybe
16
+ end
17
+
10
18
  def opening_parenthesis
11
19
  str("(")
12
20
  end
@@ -15,9 +23,31 @@ class Code
15
23
  str(")")
16
24
  end
17
25
 
26
+ def end_keyword
27
+ str("end")
28
+ end
29
+
30
+ def do_keyword
31
+ str("do")
32
+ end
33
+
34
+ def begin_keyword
35
+ str("begin")
36
+ end
37
+
18
38
  def root
19
- (opening_parenthesis << code << closing_parenthesis.maybe).aka(:group) |
20
- Call
39
+ (
40
+ opening_parenthesis.ignore << whitespace? << code <<
41
+ (whitespace? << closing_parenthesis).maybe.ignore
42
+ ).aka(:group) |
43
+ (
44
+ begin_keyword.ignore << whitespace << code <<
45
+ (whitespace? << end_keyword).maybe.ignore
46
+ ).aka(:group) |
47
+ (
48
+ do_keyword.ignore << whitespace << code <<
49
+ (whitespace? << end_keyword).maybe.ignore
50
+ ).aka(:group) | Call
21
51
  end
22
52
  end
23
53
  end
@@ -23,6 +23,22 @@ class Code
23
23
  whitespace.maybe
24
24
  end
25
25
 
26
+ def do_keyword
27
+ str("do")
28
+ end
29
+
30
+ def begin_keyword
31
+ str("begin")
32
+ end
33
+
34
+ def opening_curly_bracket
35
+ str("{")
36
+ end
37
+
38
+ def closing_curly_bracket
39
+ str("{")
40
+ end
41
+
26
42
  def if_keyword
27
43
  str("if")
28
44
  end
@@ -43,20 +59,31 @@ class Code
43
59
  str("end")
44
60
  end
45
61
 
62
+ def body
63
+ (
64
+ (begin_keyword | do_keyword).ignore << whitespace << code <<
65
+ (whitespace? << end_keyword).maybe.ignore
66
+ ) |
67
+ (
68
+ opening_curly_bracket.ignore << whitespace? << code <<
69
+ (whitespace? << closing_curly_bracket).maybe.ignore
70
+ ) | (code << (whitespace? << end_keyword).maybe.ignore)
71
+ end
72
+
46
73
  def root
47
74
  (
48
75
  (if_keyword | unless_keyword).aka(:first_operator) << whitespace <<
49
- statement.aka(:first_statement) << code.aka(:first_body) <<
76
+ statement.aka(:first_statement) << body.aka(:first_body) <<
50
77
  (
51
78
  (
52
79
  elsif_keyword.aka(:operator) << whitespace <<
53
- statement.aka(:statement) << code.aka(:body)
80
+ statement.aka(:statement) << body.aka(:body)
54
81
  ) |
55
82
  (
56
83
  else_keyword << whitespace <<
57
84
  (if_keyword | unless_keyword).aka(:operator) <<
58
- whitespace << statement.aka(:statement) << code.aka(:body)
59
- ) | (else_keyword.aka(:operator) << code.aka(:body))
85
+ whitespace << statement.aka(:statement) << body.aka(:body)
86
+ ) | (else_keyword.aka(:operator) << body.aka(:body))
60
87
  ).repeat(1).aka(:elses).maybe << end_keyword.maybe
61
88
  ).aka(:if) | statement
62
89
  end