skeem 0.0.24 → 0.0.25
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +10 -2
- data/lib/skeem/primitive/primitive_builder.rb +36 -0
- data/lib/skeem/runtime.rb +14 -2
- data/lib/skeem/s_expr_nodes.rb +10 -2
- data/lib/skeem/standard/base.skm +2 -0
- data/lib/skeem/version.rb +1 -1
- data/spec/skeem/interpreter_spec.rb +66 -1
- data/spec/skeem/primitive/primitive_builder_spec.rb +40 -8
- data/spec/skeem/runtime_spec.rb +8 -8
- data/spec/skeem/s_expr_nodes_spec.rb +36 -0
- data/spec/skeem/skm_unary_expression_spec.rb +3 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb979d01736d3b23101b56c2b7c21dff003eed46
|
4
|
+
data.tar.gz: 91dddadb24f3e6cc1aa146f7c5420d4d88708d56
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a3db261dbca2bf57909b90de1db6897026eea3baa739e80a52c2ee045eee1be23d685d903757ed1fb1ca92daac80cbbcdc9fb015d7f6daeb7d275262f5952fe
|
7
|
+
data.tar.gz: 27f38b7d92bbe22f339de58945fd7dad7efc9b57ffc1257f626fd3d97b5bd063c3432eb124e28e75d67ff35f7bf75470af15ea8ddb633850d4b21b76e122012f
|
data/README.md
CHANGED
@@ -129,6 +129,7 @@ Here are a few pointers for the Scheme programming language:
|
|
129
129
|
- Lambda expressions
|
130
130
|
- If conditionals
|
131
131
|
- Definitions
|
132
|
+
- Assignments
|
132
133
|
|
133
134
|
### Standard syntactic forms
|
134
135
|
#### define
|
@@ -155,6 +156,13 @@ __Syntax:__
|
|
155
156
|
* (quote <datum\>)
|
156
157
|
* '<datum\>
|
157
158
|
|
159
|
+
#### set!
|
160
|
+
__Purpose:__ Assign to an existing variable an expression/value to it.
|
161
|
+
__Syntax:__
|
162
|
+
* (set! <identifier\> <expression\>)
|
163
|
+
|
164
|
+
|
165
|
+
|
158
166
|
### Standard library
|
159
167
|
This section lists the implemented standard procedures
|
160
168
|
|
@@ -170,10 +178,10 @@ This section lists the implemented standard procedures
|
|
170
178
|
* `list?`, `null?`, `list`, `length`
|
171
179
|
|
172
180
|
#### String procedures
|
173
|
-
* `string?`, `string-append`, `string-length`, `string->symbol`,
|
181
|
+
* `string?`, `string=?`, `string-append`, `string-length`, `string->symbol`,
|
174
182
|
|
175
183
|
#### Symbol procedures
|
176
|
-
* `symbol
|
184
|
+
* `symbol?`, `symbol=?`
|
177
185
|
|
178
186
|
#### Vector procedures
|
179
187
|
* `vector?`, `vector`, `vector-length`, `vector-set!`
|
@@ -1,11 +1,13 @@
|
|
1
1
|
require_relative 'primitive_procedure'
|
2
2
|
require_relative '../datum_dsl'
|
3
|
+
# require_relative '../s_expr_nodes'
|
3
4
|
|
4
5
|
module Skeem
|
5
6
|
module Primitive
|
6
7
|
module PrimitiveBuilder
|
7
8
|
include DatumDSL
|
8
9
|
def add_primitives(aRuntime)
|
10
|
+
add_binding(aRuntime)
|
9
11
|
add_arithmetic(aRuntime)
|
10
12
|
add_comparison(aRuntime)
|
11
13
|
add_number_procedures(aRuntime)
|
@@ -40,6 +42,10 @@ module Skeem
|
|
40
42
|
SkmArity.new(1, '*')
|
41
43
|
end
|
42
44
|
|
45
|
+
def add_binding(aRuntime)
|
46
|
+
create_set!(aRuntime)
|
47
|
+
end
|
48
|
+
|
43
49
|
def add_arithmetic(aRuntime)
|
44
50
|
create_plus(aRuntime)
|
45
51
|
create_minus(aRuntime)
|
@@ -72,6 +78,7 @@ module Skeem
|
|
72
78
|
|
73
79
|
def add_string_procedures(aRuntime)
|
74
80
|
create_object_predicate(aRuntime, 'string?')
|
81
|
+
create_string_equal(aRuntime)
|
75
82
|
create_string_append(aRuntime)
|
76
83
|
create_string_length(aRuntime)
|
77
84
|
create_string2symbol(aRuntime)
|
@@ -102,6 +109,19 @@ module Skeem
|
|
102
109
|
create_debug(aRuntime)
|
103
110
|
end
|
104
111
|
|
112
|
+
def create_set!(aRuntime)
|
113
|
+
primitive = ->(runtime, var_ref, expr) do
|
114
|
+
if runtime.include?(var_ref.child)
|
115
|
+
redefinition = SkmDefinition.new(nil, var_ref.child, expr)
|
116
|
+
redefinition.evaluate(runtime)
|
117
|
+
else
|
118
|
+
raise StandardError, "Unbound variable: '#{var.value}'"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
define_primitive_proc(aRuntime, 'set!', binary, primitive)
|
123
|
+
end
|
124
|
+
|
105
125
|
def create_plus(aRuntime)
|
106
126
|
# arglist should be a Ruby Array
|
107
127
|
primitive = ->(runtime, arglist) do
|
@@ -338,6 +358,22 @@ module Skeem
|
|
338
358
|
define_primitive_proc(aRuntime, 'or', zero_or_more, primitive)
|
339
359
|
end
|
340
360
|
|
361
|
+
def create_string_equal(aRuntime)
|
362
|
+
primitive = ->(runtime, first_operand, arglist) do
|
363
|
+
first_one = first_operand.evaluate(runtime)
|
364
|
+
if arglist.empty?
|
365
|
+
boolean(true)
|
366
|
+
else
|
367
|
+
operands = evaluate_array(arglist, runtime)
|
368
|
+
first_value = first_one.value
|
369
|
+
all_equal = operands.all? { |elem| first_value == elem.value }
|
370
|
+
boolean(all_equal)
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
define_primitive_proc(aRuntime, 'string=?', one_or_more, primitive)
|
375
|
+
end
|
376
|
+
|
341
377
|
def create_string_append(aRuntime)
|
342
378
|
primitive = ->(runtime, arglist) do
|
343
379
|
if arglist.empty?
|
data/lib/skeem/runtime.rb
CHANGED
@@ -12,6 +12,11 @@ module Skeem
|
|
12
12
|
def include?(anIdentifier)
|
13
13
|
environment.include?(normalize_key(anIdentifier))
|
14
14
|
end
|
15
|
+
|
16
|
+
def fetch(aKey)
|
17
|
+
key_value = normalize_key(aKey)
|
18
|
+
include?(key_value) ? environment.fetch(key_value) : nil
|
19
|
+
end
|
15
20
|
|
16
21
|
def define(aKey, anEntry)
|
17
22
|
environment.define(normalize_key(aKey), anEntry)
|
@@ -20,8 +25,15 @@ module Skeem
|
|
20
25
|
def evaluate(aKey)
|
21
26
|
key_value = normalize_key(aKey)
|
22
27
|
if include?(key_value)
|
23
|
-
|
24
|
-
|
28
|
+
entry = environment.fetch(key_value)
|
29
|
+
case entry
|
30
|
+
when Primitive::PrimitiveProcedure
|
31
|
+
entry
|
32
|
+
when SkmDefinition
|
33
|
+
entry.expression.evaluate(self)
|
34
|
+
else
|
35
|
+
raise StandardError, entry.inspect
|
36
|
+
end
|
25
37
|
else
|
26
38
|
err = StandardError
|
27
39
|
key = aKey.kind_of?(SkmIdentifier) ? aKey.value : key_value
|
data/lib/skeem/s_expr_nodes.rb
CHANGED
@@ -58,8 +58,16 @@ module Skeem
|
|
58
58
|
when SkmVariableReference
|
59
59
|
other_key = expression.variable.evaluate(aRuntime)
|
60
60
|
if var_key.value != other_key.value
|
61
|
+
entry = aRuntime.fetch(other_key)
|
61
62
|
result = expression.evaluate(aRuntime)
|
62
|
-
|
63
|
+
if entry.kind_of?(Primitive::PrimitiveProcedure)
|
64
|
+
@expression = entry
|
65
|
+
elsif entry.kind_of?(SkmDefinition)
|
66
|
+
if entry.expression.kind_of?(SkmLambda)
|
67
|
+
@expression = entry.expression
|
68
|
+
end
|
69
|
+
end
|
70
|
+
else
|
63
71
|
# INFINITE LOOP DANGER: definition of 'x' is a reference to 'x'!
|
64
72
|
# Way out: the lookup for the reference should start from outer
|
65
73
|
# environment.
|
@@ -88,7 +96,7 @@ module Skeem
|
|
88
96
|
|
89
97
|
# call method should only invoked when the expression is a SkmLambda
|
90
98
|
def call(aRuntime, aProcedureCall)
|
91
|
-
unless
|
99
|
+
unless [SkmLambda, Primitive::PrimitiveProcedure].include?(expression.class)
|
92
100
|
err_msg = "Expected a SkmLambda instead of #{expression.class}"
|
93
101
|
raise StandardError, err_msg
|
94
102
|
end
|
data/lib/skeem/standard/base.skm
CHANGED
data/lib/skeem/version.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
require 'stringio'
|
2
2
|
require_relative '../spec_helper' # Use the RSpec framework
|
3
|
+
require_relative '../../lib/skeem/datum_dsl'
|
3
4
|
require_relative '../../lib/skeem/interpreter' # Load the class under test
|
4
5
|
|
5
6
|
module Skeem
|
6
7
|
describe Interpreter do
|
8
|
+
include DatumDSL
|
9
|
+
|
7
10
|
context 'Initialization:' do
|
8
11
|
it 'should be initialized without argument' do
|
9
12
|
expect { Interpreter.new() }.not_to raise_error
|
@@ -329,6 +332,41 @@ SKEEM
|
|
329
332
|
expect(result.members[index]).to eq(value)
|
330
333
|
end
|
331
334
|
end
|
335
|
+
|
336
|
+
it 'should implement the unquote of vectors' do
|
337
|
+
source = '`#( ,(+ 1 2) 4)'
|
338
|
+
result = subject.run(source)
|
339
|
+
expect(result).to be_kind_of(SkmVector)
|
340
|
+
predictions = [
|
341
|
+
[SkmInteger, 3],
|
342
|
+
[SkmInteger, 4]
|
343
|
+
]
|
344
|
+
predictions.each_with_index do |(type, value), index|
|
345
|
+
expect(result.members[index]).to be_kind_of(type)
|
346
|
+
expect(result.members[index]).to eq(value)
|
347
|
+
end
|
348
|
+
|
349
|
+
source = "`#()"
|
350
|
+
result = subject.run(source)
|
351
|
+
expect(result).to be_kind_of(SkmVector)
|
352
|
+
expect(result).to be_empty
|
353
|
+
|
354
|
+
# Nested vectors
|
355
|
+
source = '`#(a b #(,(+ 2 3) c) d)'
|
356
|
+
result = subject.run(source)
|
357
|
+
# expected: #(a b #(5 c) d)
|
358
|
+
expect(result).to be_kind_of(SkmVector)
|
359
|
+
predictions = [
|
360
|
+
[SkmIdentifier, 'a'],
|
361
|
+
[SkmIdentifier, 'b'],
|
362
|
+
[SkmVector, vector([integer(5), identifier('c')])],
|
363
|
+
[SkmIdentifier, 'd']
|
364
|
+
]
|
365
|
+
predictions.each_with_index do |(type, value), index|
|
366
|
+
expect(result.members[index]).to be_kind_of(type)
|
367
|
+
expect(result.members[index]).to eq(value)
|
368
|
+
end
|
369
|
+
end
|
332
370
|
|
333
371
|
it 'should implement the quasiquotation of lists' do
|
334
372
|
source = '(quasiquote (+ 1 2))'
|
@@ -368,10 +406,25 @@ SKEEM
|
|
368
406
|
result = subject.run(source)
|
369
407
|
expect(result).to be_kind_of(SkmList)
|
370
408
|
expect(result).to be_null
|
409
|
+
|
410
|
+
# nested lists
|
411
|
+
source = '`(a b (,(+ 2 3) c) d)'
|
412
|
+
result = subject.run(source)
|
413
|
+
# expected: (a b (5 c) d)
|
414
|
+
expect(result).to be_kind_of(SkmList)
|
415
|
+
predictions = [
|
416
|
+
[SkmIdentifier, 'a'],
|
417
|
+
[SkmIdentifier, 'b'],
|
418
|
+
[SkmList, list([integer(5), identifier('c')])],
|
419
|
+
[SkmIdentifier, 'd']
|
420
|
+
]
|
421
|
+
predictions.each_with_index do |(type, value), index|
|
422
|
+
expect(result.members[index]).to be_kind_of(type)
|
423
|
+
expect(result.members[index]).to eq(value)
|
424
|
+
end
|
371
425
|
end
|
372
426
|
=begin
|
373
427
|
`(+ 2 ,(* 3 4)) (+ 2 12)
|
374
|
-
`(a b (,(+ 2 3) c) d) (a b (5 c) d)
|
375
428
|
`(a b ,(reverse '(c d e)) f g) (a b (e d c) f g)
|
376
429
|
(let ([a 1] [b 2])
|
377
430
|
`(,a . ,b)) (1 . 2)
|
@@ -514,6 +567,18 @@ SKEEM
|
|
514
567
|
expect(result).to eq(expectation)
|
515
568
|
end
|
516
569
|
end
|
570
|
+
|
571
|
+
it 'should implement the symbol=? procedure' do
|
572
|
+
checks = [
|
573
|
+
["(symbol=? 'a 'a)", true],
|
574
|
+
["(symbol=? 'a (string->symbol \"a\"))", true],
|
575
|
+
["(symbol=? 'a 'b)", false]
|
576
|
+
]
|
577
|
+
checks.each do |(skeem_expr, expectation)|
|
578
|
+
result = subject.run(skeem_expr)
|
579
|
+
expect(result).to eq(expectation)
|
580
|
+
end
|
581
|
+
end
|
517
582
|
|
518
583
|
it 'should implement the list procedure' do
|
519
584
|
checks = [
|
@@ -6,8 +6,26 @@ require_relative '../../../lib/skeem/interpreter'
|
|
6
6
|
module Skeem
|
7
7
|
module Primitive
|
8
8
|
describe 'Testing primitive procedures' do
|
9
|
-
|
10
|
-
|
9
|
+
subject { Interpreter.new }
|
10
|
+
|
11
|
+
context 'Arithmetic operators:' do
|
12
|
+
it 'should implement the set! form' do
|
13
|
+
skeem1 = <<-SKEEM
|
14
|
+
(define x 2)
|
15
|
+
(+ x 1)
|
16
|
+
SKEEM
|
17
|
+
result = subject.run(skeem1)
|
18
|
+
expect(result.last).to eq(3) # x is bound to value 2
|
19
|
+
skeem2 = <<-SKEEM
|
20
|
+
(set! x 4)
|
21
|
+
(+ x 1)
|
22
|
+
SKEEM
|
23
|
+
result = subject.run(skeem2)
|
24
|
+
expect(result.last).to eq(5) # x is now bound to value 4
|
25
|
+
end
|
26
|
+
end # context
|
27
|
+
|
28
|
+
context 'Arithmetic operators:' do
|
11
29
|
it 'should implement the addition operator' do
|
12
30
|
[
|
13
31
|
['(+)', 0], # '+' as nullary operator. Example from section 6.2.6
|
@@ -294,6 +312,18 @@ module Skeem
|
|
294
312
|
end
|
295
313
|
end
|
296
314
|
|
315
|
+
it 'should implement the string=? procedure' do
|
316
|
+
checks = [
|
317
|
+
['(string=? "Mom" "Mom")', true],
|
318
|
+
['(string=? "Mom" "Mum")', false],
|
319
|
+
['(string=? "Mom" "Dad")', false]
|
320
|
+
]
|
321
|
+
checks.each do |(skeem_expr, expectation)|
|
322
|
+
result = subject.run(skeem_expr)
|
323
|
+
expect(result).to eq(expectation)
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
297
327
|
it 'should implement the string-append procedure' do
|
298
328
|
checks = [
|
299
329
|
['(string-append)', ''],
|
@@ -323,22 +353,24 @@ module Skeem
|
|
323
353
|
it 'should implement the symbol? procedure' do
|
324
354
|
checks = [
|
325
355
|
['(symbol? #f)', false],
|
326
|
-
['(symbol? "bar")', false]
|
356
|
+
['(symbol? "bar")', false],
|
357
|
+
["(symbol? '())", false],
|
358
|
+
["(symbol? 'foo)", true],
|
327
359
|
]
|
328
360
|
checks.each do |(skeem_expr, expectation)|
|
329
361
|
result = subject.run(skeem_expr)
|
330
362
|
expect(result).to eq(expectation)
|
331
363
|
end
|
332
|
-
end
|
364
|
+
end
|
333
365
|
end # context
|
334
366
|
|
335
367
|
context 'List procedures:' do
|
336
368
|
it 'should implement the list? procedure' do
|
337
369
|
checks = [
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
370
|
+
['(list? #f)', false],
|
371
|
+
['(list? 1)', false],
|
372
|
+
['(list? "bar")', false],
|
373
|
+
['(list? (list 1 2 3))', true],
|
342
374
|
['(list? (list))', true]
|
343
375
|
]
|
344
376
|
checks.each do |(skeem_expr, expectation)|
|
data/spec/skeem/runtime_spec.rb
CHANGED
@@ -39,14 +39,14 @@ module Skeem
|
|
39
39
|
context 'Evaluation:' do
|
40
40
|
include Primitive::PrimitiveBuilder
|
41
41
|
|
42
|
-
it 'should evaluate a given entry' do
|
43
|
-
entry =
|
44
|
-
result = double('fake-procedure')
|
45
|
-
expect(entry).to receive(:expression).and_return(result)
|
46
|
-
expect(result).to receive(:evaluate).with(subject).and_return(integer(3))
|
47
|
-
subject.define('three', entry)
|
48
|
-
expect(subject.evaluate('three')).to eq(3)
|
49
|
-
end
|
42
|
+
# it 'should evaluate a given entry' do
|
43
|
+
# entry = integer(3)
|
44
|
+
# result = double('fake-procedure')
|
45
|
+
# expect(entry).to receive(:expression).and_return(result)
|
46
|
+
# expect(result).to receive(:evaluate).with(subject).and_return(integer(3))
|
47
|
+
# subject.define('three', entry)
|
48
|
+
# expect(subject.evaluate('three')).to eq(3)
|
49
|
+
# end
|
50
50
|
|
51
51
|
it 'should evaluate a given list' do
|
52
52
|
add_primitives(subject)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'ostruct'
|
2
2
|
require_relative '../spec_helper' # Use the RSpec framework
|
3
3
|
require_relative '../../lib/skeem/runtime'
|
4
|
+
require_relative '../../lib/skeem/primitive/primitive_builder'
|
4
5
|
require_relative '../../lib/skeem/s_expr_nodes' # Load the classes under test
|
5
6
|
|
6
7
|
module Skeem
|
@@ -26,6 +27,8 @@ module Skeem
|
|
26
27
|
end # context
|
27
28
|
|
28
29
|
context 'Provided services:' do
|
30
|
+
include Primitive::PrimitiveBuilder
|
31
|
+
|
29
32
|
let(:runtime) { Runtime.new(Environment.new) }
|
30
33
|
|
31
34
|
it 'should create an entry when evaluating' do
|
@@ -34,6 +37,39 @@ module Skeem
|
|
34
37
|
expect(runtime).to include(sample_symbol)
|
35
38
|
end
|
36
39
|
|
40
|
+
it 'should optimize an entry that aliases a primitive proc' do
|
41
|
+
add_primitives(runtime)
|
42
|
+
identifier = SkmIdentifier.create('plus')
|
43
|
+
proc_name = SkmIdentifier.create('+')
|
44
|
+
var_ref = SkmVariableReference.new(nil, proc_name)
|
45
|
+
instance = SkmDefinition.new(nil, identifier, var_ref) # (define plus +)
|
46
|
+
expect(instance.expression).to eq(var_ref)
|
47
|
+
instance.evaluate(runtime)
|
48
|
+
# Optimization by getting rid of indirection
|
49
|
+
expect(instance.expression).to be_kind_of(Primitive::PrimitiveProcedure)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should optimize an entry that aliases a lambda proc' do
|
53
|
+
# Let's define a (dummy) lambda
|
54
|
+
formals = SkmFormals.new([], :fixed)
|
55
|
+
dummy_body = { :defs => [], :sequence => [SkmInteger.create(3)]}
|
56
|
+
lbd = SkmLambda.new(nil, formals, dummy_body)
|
57
|
+
id = SkmIdentifier.create('some-lambda')
|
58
|
+
def1 = SkmDefinition.new(nil, id, lbd)
|
59
|
+
def1.evaluate(runtime)
|
60
|
+
|
61
|
+
# Let's create an alias to the lambda
|
62
|
+
other_name = SkmIdentifier.create('aliased-lambda')
|
63
|
+
var_ref = SkmVariableReference.new(nil, id)
|
64
|
+
|
65
|
+
# (define aliased-lambda some-lambda)
|
66
|
+
def2 = SkmDefinition.new(nil, other_name, var_ref)
|
67
|
+
expect(def2.expression).to eq(var_ref)
|
68
|
+
def2.evaluate(runtime)
|
69
|
+
# Optimization by getting rid of indirection
|
70
|
+
expect(def2.expression).to eq(lbd)
|
71
|
+
end
|
72
|
+
|
37
73
|
it 'should quasiquote its variable and expression' do
|
38
74
|
alter_ego = subject.quasiquote(runtime)
|
39
75
|
expect(alter_ego).to eq(subject)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require_relative '../spec_helper' # Use the RSpec framework
|
2
2
|
require_relative '../../lib/skeem/datum_dsl'
|
3
3
|
require_relative '../../lib/skeem/environment'
|
4
|
+
require_relative '../../lib/skeem/s_expr_nodes'
|
4
5
|
require_relative '../../lib/skeem/skm_unary_expression' # Load the classes under test
|
5
6
|
|
6
7
|
module Skeem
|
@@ -176,15 +177,14 @@ module Skeem
|
|
176
177
|
end # context
|
177
178
|
|
178
179
|
context 'Provided services:' do
|
179
|
-
let(:
|
180
|
+
let(:sample_def) { SkmDefinition.new(nil, identifier('three'), integer(3)) }
|
180
181
|
let(:runtime) { Runtime.new(Environment.new) }
|
181
182
|
|
182
183
|
before(:each) do
|
183
|
-
runtime.define('three',
|
184
|
+
runtime.define('three', sample_def)
|
184
185
|
end
|
185
186
|
|
186
187
|
it "should return the variable's value at evaluation" do
|
187
|
-
expect(dummy_def).to receive(:expression).and_return(integer(3))
|
188
188
|
expect(subject.evaluate(runtime)).to eq(3)
|
189
189
|
end
|
190
190
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: skeem
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.25
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitri Geshef
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-11-
|
11
|
+
date: 2018-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rley
|