safestruct 0.2.0 → 1.0.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 74b37cac746195871cc30eec8b8b54622958c6a5
4
- data.tar.gz: 80def63037cd23ce8812529a4f208e1ebfbbab7a
3
+ metadata.gz: c7bf46e7fc7abcced2da4628ab2640f4f3136482
4
+ data.tar.gz: 693e1ad041258390403893df801673955e574c7e
5
5
  SHA512:
6
- metadata.gz: 508027ee5576e342154bc62d6d5b5e25cf2f829a075a7b942fc9a3af2bb2295f6e6d71eec58597b7de5c69106ecde9ee6fb1f8d0c503215ab7f15735afa01f62
7
- data.tar.gz: a9172d32b881902e273bc54cb4e41875edb0c2dd40efd62ca19a07170e8cf01596457b31fa1c63fe244096c3a69b2ab9a280c93241656abedf99f1fd5eeb4c60
6
+ metadata.gz: 2f548ea0b261a9fe0e829ad2205aa21b46ea6cac99ff082a80bcaaa5418fe75e9684200f31033f099450c3b688240664949ad0bbc70ad4f8abf57f197a33020a
7
+ data.tar.gz: 9fc0faf2c9373cfa146a7f7d5d8b18e17c7ea6e419d10b19d9ab95323650d825bbb3e6b7818c475360aa89101c9f17543731bc07dd02f2e17ce102a5ede5e92e
data/LICENSE.md ADDED
@@ -0,0 +1,116 @@
1
+ CC0 1.0 Universal
2
+
3
+ Statement of Purpose
4
+
5
+ The laws of most jurisdictions throughout the world automatically confer
6
+ exclusive Copyright and Related Rights (defined below) upon the creator and
7
+ subsequent owner(s) (each and all, an "owner") of an original work of
8
+ authorship and/or a database (each, a "Work").
9
+
10
+ Certain owners wish to permanently relinquish those rights to a Work for the
11
+ purpose of contributing to a commons of creative, cultural and scientific
12
+ works ("Commons") that the public can reliably and without fear of later
13
+ claims of infringement build upon, modify, incorporate in other works, reuse
14
+ and redistribute as freely as possible in any form whatsoever and for any
15
+ purposes, including without limitation commercial purposes. These owners may
16
+ contribute to the Commons to promote the ideal of a free culture and the
17
+ further production of creative, cultural and scientific works, or to gain
18
+ reputation or greater distribution for their Work in part through the use and
19
+ efforts of others.
20
+
21
+ For these and/or other purposes and motivations, and without any expectation
22
+ of additional consideration or compensation, the person associating CC0 with a
23
+ Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
24
+ and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
25
+ and publicly distribute the Work under its terms, with knowledge of his or her
26
+ Copyright and Related Rights in the Work and the meaning and intended legal
27
+ effect of CC0 on those rights.
28
+
29
+ 1. Copyright and Related Rights. A Work made available under CC0 may be
30
+ protected by copyright and related or neighboring rights ("Copyright and
31
+ Related Rights"). Copyright and Related Rights include, but are not limited
32
+ to, the following:
33
+
34
+ i. the right to reproduce, adapt, distribute, perform, display, communicate,
35
+ and translate a Work;
36
+
37
+ ii. moral rights retained by the original author(s) and/or performer(s);
38
+
39
+ iii. publicity and privacy rights pertaining to a person's image or likeness
40
+ depicted in a Work;
41
+
42
+ iv. rights protecting against unfair competition in regards to a Work,
43
+ subject to the limitations in paragraph 4(a), below;
44
+
45
+ v. rights protecting the extraction, dissemination, use and reuse of data in
46
+ a Work;
47
+
48
+ vi. database rights (such as those arising under Directive 96/9/EC of the
49
+ European Parliament and of the Council of 11 March 1996 on the legal
50
+ protection of databases, and under any national implementation thereof,
51
+ including any amended or successor version of such directive); and
52
+
53
+ vii. other similar, equivalent or corresponding rights throughout the world
54
+ based on applicable law or treaty, and any national implementations thereof.
55
+
56
+ 2. Waiver. To the greatest extent permitted by, but not in contravention of,
57
+ applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
58
+ unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
59
+ and Related Rights and associated claims and causes of action, whether now
60
+ known or unknown (including existing as well as future claims and causes of
61
+ action), in the Work (i) in all territories worldwide, (ii) for the maximum
62
+ duration provided by applicable law or treaty (including future time
63
+ extensions), (iii) in any current or future medium and for any number of
64
+ copies, and (iv) for any purpose whatsoever, including without limitation
65
+ commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
66
+ the Waiver for the benefit of each member of the public at large and to the
67
+ detriment of Affirmer's heirs and successors, fully intending that such Waiver
68
+ shall not be subject to revocation, rescission, cancellation, termination, or
69
+ any other legal or equitable action to disrupt the quiet enjoyment of the Work
70
+ by the public as contemplated by Affirmer's express Statement of Purpose.
71
+
72
+ 3. Public License Fallback. Should any part of the Waiver for any reason be
73
+ judged legally invalid or ineffective under applicable law, then the Waiver
74
+ shall be preserved to the maximum extent permitted taking into account
75
+ Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
76
+ is so judged Affirmer hereby grants to each affected person a royalty-free,
77
+ non transferable, non sublicensable, non exclusive, irrevocable and
78
+ unconditional license to exercise Affirmer's Copyright and Related Rights in
79
+ the Work (i) in all territories worldwide, (ii) for the maximum duration
80
+ provided by applicable law or treaty (including future time extensions), (iii)
81
+ in any current or future medium and for any number of copies, and (iv) for any
82
+ purpose whatsoever, including without limitation commercial, advertising or
83
+ promotional purposes (the "License"). The License shall be deemed effective as
84
+ of the date CC0 was applied by Affirmer to the Work. Should any part of the
85
+ License for any reason be judged legally invalid or ineffective under
86
+ applicable law, such partial invalidity or ineffectiveness shall not
87
+ invalidate the remainder of the License, and in such case Affirmer hereby
88
+ affirms that he or she will not (i) exercise any of his or her remaining
89
+ Copyright and Related Rights in the Work or (ii) assert any associated claims
90
+ and causes of action with respect to the Work, in either case contrary to
91
+ Affirmer's express Statement of Purpose.
92
+
93
+ 4. Limitations and Disclaimers.
94
+
95
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
96
+ surrendered, licensed or otherwise affected by this document.
97
+
98
+ b. Affirmer offers the Work as-is and makes no representations or warranties
99
+ of any kind concerning the Work, express, implied, statutory or otherwise,
100
+ including without limitation warranties of title, merchantability, fitness
101
+ for a particular purpose, non infringement, or the absence of latent or
102
+ other defects, accuracy, or the present or absence of errors, whether or not
103
+ discoverable, all to the greatest extent permissible under applicable law.
104
+
105
+ c. Affirmer disclaims responsibility for clearing rights of other persons
106
+ that may apply to the Work or any use thereof, including without limitation
107
+ any person's Copyright and Related Rights in the Work. Further, Affirmer
108
+ disclaims responsibility for obtaining any necessary consents, permissions
109
+ or other rights required for any use of the Work.
110
+
111
+ d. Affirmer understands and acknowledges that Creative Commons is not a
112
+ party to this document and has no duty or obligation with respect to this
113
+ CC0 or use of the Work.
114
+
115
+ For more information, please see
116
+ <http://creativecommons.org/publicdomain/zero/1.0/
data/Manifest.txt CHANGED
@@ -1,4 +1,5 @@
1
1
  CHANGELOG.md
2
+ LICENSE.md
2
3
  Manifest.txt
3
4
  README.md
4
5
  Rakefile
data/README.md CHANGED
@@ -83,7 +83,7 @@ voter2 == Voter.zero #=> false
83
83
 
84
84
  Voter.zero.frozen? #=> true
85
85
 
86
- voter3 = Voter.new( 0 ) #=> ArgumentError - wrong number of arguments
86
+ voter3 = Voter.new( 0 ) #=> ArgumentError: wrong number of arguments
87
87
  # for Voter.new - 1 for 4
88
88
  ```
89
89
 
@@ -101,7 +101,7 @@ Example:
101
101
  ArrayInteger = SafeArray.build_class( Integer )
102
102
  ary = ArrayInteger.new
103
103
  ary.size #=> 0
104
- ary[0] #=> IndexError
104
+ ary[0] #=> IndexError: index 0 outside of array bounds
105
105
  ary.size = 2 #=> [0,0]
106
106
  ary[0] #=> 0
107
107
  ```
@@ -111,7 +111,7 @@ or use the `Array.of` convenience shortcut:
111
111
  ``` ruby
112
112
  ary = Array.of( Integer )
113
113
  ary.size #=> 0
114
- ary[0] #=> IndexError
114
+ ary[0] #=> IndexError: index 0 outside of array bounds
115
115
  ary.size = 2 #=> [0, 0]
116
116
  ary[0] #=> 0
117
117
 
@@ -119,7 +119,7 @@ ary[0] #=> 0
119
119
 
120
120
  another_ary = Array.of( Bool )
121
121
  another_ary.size #=> 0
122
- another_ary[0] #=> IndexError
122
+ another_ary[0] #=> IndexError: index 0 outside of array bounds
123
123
  another_ary.size = 2 #=> [false, false]
124
124
  another_ary[0] #=> false
125
125
 
@@ -135,7 +135,7 @@ Yes, Safe Array works with structs (or nested arrays or hash mappings) too. Exam
135
135
  ``` ruby
136
136
  ary = Array.of( Vote )
137
137
 
138
- ary[0] #=> IndexError
138
+ ary[0] #=> IndexError: index 0 outside of array bounds
139
139
  ary.size = 2 #=> [#<Vote @weight=0, @voted=false, @vote=0, @delegate='0x0000'>,
140
140
  # #<Vote @weight=0, @voted=false, @vote=0, @delegate='0x0000'>]
141
141
  ary[0] #=> #<Vote @weight=0, @voted=false, @vote=0, @delegate='0x0000'>
data/lib/safestruct.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'pp'
4
+ require 'forwardable' # uses def_delegator
4
5
 
5
6
 
6
7
  ## our own code
@@ -13,16 +14,24 @@ require 'safestruct/safe_struct'
13
14
 
14
15
 
15
16
  ####################################
16
- ## add dummy bool class for mapping and (payable) method signature
17
+ ## add zero/zero_new machinery for builin classes
17
18
 
19
+ #### value semantics
18
20
  class Integer
19
- def self.zero() 0; end
21
+ def self.zero() 0; end ## note: 0.frozen? == true by default
20
22
  end
21
23
 
22
24
  class Bool
23
- def self.zero() false; end
25
+ def self.zero() false; end ## note: false.frozen? == true by default
24
26
  end
25
27
 
28
+ #### reference semantics (new copy ALWAYS needed)
29
+ class String
30
+ def self.new_zero() new; end
31
+ def self.zero() @zero ||= new_zero.freeze; end
32
+ end
33
+
34
+
26
35
 
27
36
 
28
37
  #####
@@ -50,13 +59,16 @@ end
50
59
 
51
60
  class Array
52
61
  ## "typed" safe array "constructor"
53
- ## e.g. Array.of( Address ) or Array.of( Money ) or Array.of( Proposal, size: 2 ) etc.
54
- def self.of( klass_value )
62
+ ## e.g. Array.of( Address ) or Array.of( Money ) or
63
+ ## Array.of( Proposal, 2 ) etc.
64
+ def self.of( klass_value, size=0 )
55
65
  klass = Safe::SafeArray.build_class( klass_value )
56
- klass.new ## todo: add klass.new( **kwargs ) for size: 2 etc.
66
+ klass.new( size )
57
67
  end
58
68
  end
59
69
 
70
+
71
+
60
72
  module Safe
61
73
  ############################
62
74
  # note: HACK redefine built in struct in module Safe "context"
@@ -13,50 +13,84 @@ class SafeArray
13
13
  ## note: keep a class cache
14
14
  cache = @@cache ||= {}
15
15
  klass = cache[ klass_value ]
16
- return klass if klass
17
16
 
18
- klass = Class.new( SafeArray )
19
- klass.class_eval( <<RUBY )
20
- def self.klass_value
21
- @klass_value ||= #{klass_value}
22
- end
17
+ if klass.nil?
18
+
19
+ klass = Class.new( SafeArray )
20
+ klass.class_eval( <<RUBY )
21
+ def self.klass_value
22
+ @klass_value ||= #{klass_value}
23
+ end
23
24
  RUBY
24
- ## add to cache for later (re)use
25
- cache[ klass_value ] = klass
25
+ ## add to cache for later (re)use
26
+ cache[ klass_value ] = klass
27
+ end
26
28
  klass
27
29
  end
28
30
 
29
31
 
30
32
  def self.new_zero() new; end
31
- def self.zero() @zero ||= new_zero; end
33
+ def self.zero() @zero ||= new_zero.freeze; end
32
34
 
33
35
 
34
36
 
35
- def initialize
37
+ def initialize( size=0 )
36
38
  ## todo/check: if array works if value is a (nested/multi-dimensional) array
37
39
  @ary = []
40
+ self.size = size if size > 0 ## auto-init with zeros
41
+ self # return reference to self
42
+ end
43
+
44
+ def freeze
45
+ super
46
+ @ary.freeze ## note: pass on freeze to "wrapped" array
47
+ self # return reference to self
48
+ end
49
+
50
+
51
+ def ==( other )
52
+ if other.is_a?( self.class ) ## note: must be same array class
53
+ @ary == other.instance_variable_get( '@ary' ) ## compare "wrapped" array
54
+ else
55
+ false
56
+ end
38
57
  end
58
+ alias_method :eql?, :==
59
+
60
+
61
+ def size=(value)
62
+ ## todo/check: value must be greater 0 and greater than current size
63
+ diff = value - @ary.size
64
+
65
+ ## todo/check:
66
+ ## always return (deep) frozen zero object - why? why not?
67
+ ## let user change the returned zero object - why? why not?
68
+ if self.class.klass_value.respond_to?( :new_zero )
69
+ ## note: use a new unfrozen copy of the zero object
70
+ ## changes to the object MUST be possible (new "empty" modifable object expected)
71
+ diff.times { @ary << self.class.klass_value.new_zero }
72
+ else # assume value semantics e.g. Integer, Bool, etc. zero values gets replaced
73
+ ## puts "use value semantics"
74
+ diff.times { @ary << self.class.klass_value.zero }
75
+ end
76
+ self # return reference to self
77
+ end
78
+ alias_method :'length=', :'size='
79
+
39
80
 
40
81
  def []=(index, value)
82
+ ## note: use fetch
83
+ # throws / raises an IndexError exception
84
+ # if the referenced index lies outside of the array bounds
85
+ # todo/fix: is there a better way to check for index out-of-bounds error?
86
+ old_value = @ary.fetch( index )
41
87
  @ary[index] = value
42
88
  end
43
89
 
44
90
  def [](index)
45
- item = @ary[ index ]
46
- if item.nil?
47
- ## todo/check:
48
- ## always return (deep) frozen zero object - why? why not?
49
- ## let user change the returned zero object - why? why not?
50
- if self.class.klass_value.respond_to?( :new_zero )
51
- ## note: use a new unfrozen copy of the zero object
52
- ## changes to the object MUST be possible (new "empty" modifable object expected)
53
- item = self.class.klass_value.new_zero
54
- else # assume value semantics e.g. Integer, Bool, etc. zero values gets replaced
55
- ## puts "use value semantics"
56
- item = self.class.klass_value.zero
57
- end
58
- end
59
- item
91
+ ## note: throws / raises an IndexError exception
92
+ # if the referenced index lies outside of the array bounds
93
+ @ary.fetch( index )
60
94
  end
61
95
 
62
96
  def push( item )
@@ -66,7 +100,10 @@ RUBY
66
100
  @ary.push( item )
67
101
  end
68
102
 
69
- def size() @ary.size; end
70
- def length() size; end
103
+ extend Forwardable
104
+ def_delegators :@ary, :size, :length,
105
+ :each, :each_with_index
106
+
107
+
71
108
  end # class SafeArray
72
109
  end # module Safe
@@ -19,32 +19,51 @@ class SafeHash
19
19
  ## note: keep a class cache
20
20
  cache = @@cache ||= {}
21
21
  klass = cache[ klass_value ]
22
- return klass if klass
23
-
24
- klass = Class.new( SafeHash )
25
- klass.class_eval( <<RUBY )
26
- def self.klass_key
27
- @klass_key ||= #{klass_key}
28
- end
29
- def self.klass_value
30
- @klass_value ||= #{klass_value}
31
- end
22
+
23
+ if klass.nil?
24
+ klass = Class.new( SafeHash )
25
+ klass.class_eval( <<RUBY )
26
+ def self.klass_key
27
+ @klass_key ||= #{klass_key}
28
+ end
29
+ def self.klass_value
30
+ @klass_value ||= #{klass_value}
31
+ end
32
32
  RUBY
33
- ## add to cache for later (re)use
34
- cache[ klass_value ] = klass
33
+ ## add to cache for later (re)use
34
+ cache[ klass_value ] = klass
35
+ end
36
+
35
37
  klass
36
38
  end
37
39
 
38
40
 
39
41
  def self.new_zero() new; end
40
- def self.zero() @zero ||= new_zero; end
42
+ def self.zero() @zero ||= new_zero.freeze; end
41
43
 
42
44
 
43
45
  def initialize
44
46
  ## todo/check: if hash works if value is a (nested) hash
45
- @h = {}
47
+ @h = {}
46
48
  end
47
49
 
50
+ def freeze
51
+ super
52
+ @h.freeze ## note: pass on freeze to "wrapped" hash
53
+ self # return reference to self
54
+ end
55
+
56
+ def ==( other )
57
+ if other.is_a?( self.class ) ## note: must be same hash class
58
+ @h == other.instance_variable_get( '@h' ) ## compare "wrapped" hash
59
+ else
60
+ false
61
+ end
62
+ end
63
+ alias_method :eql?, :==
64
+
65
+
66
+
48
67
 
49
68
  def []=(key, value)
50
69
  @h[key] = value
@@ -73,7 +92,9 @@ RUBY
73
92
  item
74
93
  end
75
94
 
76
- def size() @h.size; end
77
- def length() size; end
95
+ extend Forwardable
96
+ def_delegators :@h, :size, :length, ## todo/fix: remove size and length for (safe) hash - why? why not?
97
+ :has_key?, :key?
98
+
78
99
  end # class SafeHash
79
100
  end # module Safe
@@ -27,11 +27,23 @@ def self.build_class( **attributes )
27
27
  end
28
28
  end
29
29
 
30
+ alias_method :old_freeze, :freeze # note: store "old" orginal version of freeze
31
+ define_method( :freeze ) do
32
+ old_freeze ## same as calling super
33
+ attributes.keys.each do |key|
34
+ instance_variable_get( "@#{key}" ).freeze
35
+ end
36
+ self # return reference to self
37
+ end
38
+
30
39
  define_method( :== ) do |other|
31
- return false unless other.is_a?( klass )
32
- attributes.keys.all? do |key|
33
- __send__( key ) == other.__send__( key )
34
- end
40
+ if other.is_a?( klass )
41
+ attributes.keys.all? do |key|
42
+ __send__( key ) == other.__send__( key )
43
+ end
44
+ else
45
+ false
46
+ end
35
47
  end
36
48
  alias_method :eql?, :==
37
49
  end
@@ -54,10 +66,14 @@ def self.build_class( **attributes )
54
66
  ## use new_zero to create a new instance!!!
55
67
  ## do NOT use the passed in reference!!!!
56
68
  values = attributes.values.map do |value|
57
- if value.is_a?(SafeStruct) ||
58
- value.is_a?(SafeArray) ||
59
- value.is_a?(SafeHash)
60
- value.class.new_zero
69
+ ## note: was: use more "generic" check for respond_to?( :new_zero )
70
+ ## value.is_a?(SafeStruct) ||
71
+ ## value.is_a?(SafeArray) ||
72
+ ## value.is_a?(SafeHash)
73
+ if value.is_a?(String) && value == '0x0000'
74
+ value.dup ## special case for Address(0) or Address.zero encoded as string for now!!!!
75
+ elsif value.class.respond_to?( :new_zero )
76
+ value.class.new_zero
61
77
  else
62
78
  ## assume "value" object / semantics (e.g. 0, false, '0x0000' etc.) and pass through
63
79
  value
@@ -3,8 +3,8 @@
3
3
 
4
4
  module Safe
5
5
 
6
- MAJOR = 0
7
- MINOR = 2
6
+ MAJOR = 1
7
+ MINOR = 0
8
8
  PATCH = 0
9
9
  VERSION = [MAJOR,MINOR,PATCH].join('.')
10
10
 
data/test/test_array.rb CHANGED
@@ -17,7 +17,7 @@ class TestArray < MiniTest::Test
17
17
 
18
18
  def test_integer
19
19
  pp Array_Integer
20
- pp ary = Array_Integer.new
20
+ pp ary = Array_Integer.new(2)
21
21
 
22
22
  assert_equal Integer, Array_Integer.klass_value
23
23
  assert_equal 0, ary[0]
@@ -28,6 +28,23 @@ def test_integer
28
28
  assert_equal 101, ary[0]
29
29
  assert_equal 102, ary[1]
30
30
 
31
+ assert_equal 2, ary.size
32
+ assert_equal 2, ary.length
33
+ assert_equal false, ary.frozen?
34
+
35
+ ary.each { |item| pp item }
36
+ ary.each_with_index { |item,i| puts "[#{i}] #{item}"}
37
+
38
+ ary.size = 3
39
+ assert_equal 3, ary.size
40
+ assert_equal 0, ary[2]
41
+ assert Array_Integer.zero != ary
42
+
43
+ pp Array_Integer.zero
44
+ assert_equal true, Array_Integer.zero.frozen?
45
+ assert_equal Array_Integer.zero, Array_Integer.zero
46
+ assert_equal Array_Integer.zero, Array_Integer.new
47
+
31
48
  ## check Array.of (uses cached classes)
32
49
  assert_equal Array_Integer, Array.of( Integer ).class
33
50
  end
@@ -35,7 +52,7 @@ end
35
52
 
36
53
  def test_bool
37
54
  pp Array_Bool
38
- pp ary = Array_Bool.new
55
+ pp ary = Array_Bool.new(2)
39
56
 
40
57
  assert_equal Bool, Array_Bool.klass_value
41
58
  assert_equal false, ary[0]
data/test/test_hash.rb CHANGED
@@ -23,6 +23,22 @@ def test_integer
23
23
  pp Hash_X_Integer
24
24
  pp h = Hash_X_Integer.new
25
25
 
26
+ assert_equal false, h.key?( '0x1111' )
27
+ assert_equal false, h.has_key?( '0x1111' )
28
+
29
+ ## todo/fix: remove size and length for (safe) hash - why? why not?
30
+ assert_equal 0, h.size
31
+ assert_equal 0, h.length
32
+
33
+ assert_equal Hash_X_Integer.zero, h
34
+ assert_equal Hash_X_Integer.zero, Hash_X_Integer.new
35
+
36
+ pp Hash_X_Integer.zero
37
+ assert_equal true, Hash_X_Integer.zero.frozen?
38
+ assert_equal false, Hash_X_Integer.new.frozen?
39
+ assert_equal false, h.frozen?
40
+
41
+
26
42
  assert_equal Integer, Hash_X_Integer.klass_value
27
43
  assert_equal 0, h['0x1111']
28
44
  assert_equal 0, h['0x2222']
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safestruct
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-15 00:00:00.000000000 Z
11
+ date: 2019-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rdoc
@@ -45,10 +45,12 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files:
47
47
  - CHANGELOG.md
48
+ - LICENSE.md
48
49
  - Manifest.txt
49
50
  - README.md
50
51
  files:
51
52
  - CHANGELOG.md
53
+ - LICENSE.md
52
54
  - Manifest.txt
53
55
  - README.md
54
56
  - Rakefile