ryo.rb 0.5.5 → 0.5.7

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/specs.yml +2 -2
  3. data/.rubocop.yml +2 -0
  4. data/README.md +46 -27
  5. data/lib/ryo/basic_object.rb +7 -11
  6. data/lib/ryo/builder.rb +35 -54
  7. data/lib/ryo/enumerable.rb +62 -79
  8. data/lib/ryo/json.rb +6 -11
  9. data/lib/ryo/keywords.rb +16 -28
  10. data/lib/ryo/object.rb +6 -10
  11. data/lib/ryo/reflect.rb +54 -170
  12. data/lib/ryo/utils.rb +68 -0
  13. data/lib/ryo/version.rb +1 -1
  14. data/lib/ryo/yaml.rb +6 -11
  15. data/lib/ryo.rb +26 -37
  16. data/ryo.rb.gemspec +1 -0
  17. data/share/{ryo.rb/examples → examples/ryo.rb}/1.0_prototypes_point_object.rb +1 -0
  18. data/share/{ryo.rb/examples → examples/ryo.rb}/1.1_prototypes_ryo_fn.rb +1 -0
  19. data/share/{ryo.rb/examples → examples/ryo.rb}/2.0_iteration_each.rb +1 -0
  20. data/share/{ryo.rb/examples → examples/ryo.rb}/2.1_iteration_map.rb +1 -0
  21. data/share/{ryo.rb/examples → examples/ryo.rb}/2.2_iteration_ancestors.rb +1 -0
  22. data/share/examples/ryo.rb/3.0_recursion_ryo_from.rb +20 -0
  23. data/share/{ryo.rb/examples → examples/ryo.rb}/3.1_recursion_ryo_from_with_array.rb +5 -4
  24. data/share/{ryo.rb/examples → examples/ryo.rb}/3.2_recursion_ryo_from_with_openstruct.rb +3 -3
  25. data/share/{ryo.rb/examples → examples/ryo.rb}/4.0_basicobject_ryo_basicobject.rb +1 -0
  26. data/share/{ryo.rb/examples → examples/ryo.rb}/4.1_basicobject_ryo_basicobject_from.rb +1 -0
  27. data/share/{ryo.rb/examples → examples/ryo.rb}/5_collisions_resolution_strategy.rb +1 -0
  28. data/share/{ryo.rb/examples → examples/ryo.rb}/6_beyond_hash_objects.rb +1 -0
  29. data/share/{ryo.rb/examples → examples/ryo.rb}/7_ryo_memo.rb +1 -0
  30. data/share/ryo.rb/NEWS +11 -0
  31. data/spec/readme_spec.rb +2 -2
  32. data/spec/ryo_enumerable_spec.rb +1 -1
  33. data/spec/ryo_json_spec.rb +1 -1
  34. data/spec/ryo_keywords_spec.rb +1 -1
  35. data/spec/ryo_prototypes_spec.rb +1 -1
  36. data/spec/ryo_reflect_spec.rb +8 -0
  37. data/spec/ryo_spec.rb +1 -1
  38. data/spec/ryo_yaml_spec.rb +1 -1
  39. metadata +34 -18
  40. data/share/ryo.rb/examples/3.0_recursion_ryo_from.rb +0 -13
  41. /data/share/{ryo.rb/examples → examples/ryo.rb}/setup.rb +0 -0
  42. /data/{LICENSE → share/ryo.rb/LICENSE} +0 -0
data/lib/ryo.rb CHANGED
@@ -15,6 +15,9 @@
15
15
  # point = Ryo.assign(Ryo({}), {x: 0}, {y: 0})
16
16
  # point.x # => 0
17
17
  module Ryo
18
+ require_relative "ryo/json"
19
+ require_relative "ryo/yaml"
20
+ require_relative "ryo/utils"
18
21
  require_relative "ryo/reflect"
19
22
  require_relative "ryo/keywords"
20
23
  require_relative "ryo/builder"
@@ -30,13 +33,11 @@ module Ryo
30
33
 
31
34
  ##
32
35
  # @param [<Ryo::Object, Ryo::BasicObject>] ryo
33
- # A Ryo object.
34
- #
36
+ # A Ryo object
35
37
  # @param [Module] mod
36
- # A module to extend a Ryo object with.
37
- #
38
+ # The module to extend a Ryo object with
38
39
  # @return [<Ryo::Object, Ryo::BasicObject>]
39
- # Returns a Ryo object extended by **mod**.
40
+ # Returns an extended Ryo object
40
41
  def self.extend!(ryo, mod)
41
42
  kernel(:extend).bind_call(ryo, mod)
42
43
  end
@@ -45,10 +46,9 @@ module Ryo
45
46
  # Duplicates a Ryo object, and its prototype(s).
46
47
  #
47
48
  # @param [<Ryo::Object, Ryo::BasicObject>] ryo
48
- # A Ryo object.
49
- #
49
+ # A Ryo object
50
50
  # @return [<Ryo::Object, Ryo::BasicObject>]
51
- # Returns a duplicated Ryo object.
51
+ # Returns a duplicated Ryo object
52
52
  def self.dup(ryo)
53
53
  duplicate = extend!(
54
54
  kernel(:dup).bind_call(ryo),
@@ -61,13 +61,12 @@ module Ryo
61
61
  end
62
62
 
63
63
  ##
64
- # Creates a memoized Ryo value.
64
+ # Creates a memoized Ryo value
65
65
  #
66
66
  # @param [Proc] b
67
- # A Proc that is memoized after being accessed for the first time.
68
- #
67
+ # A Proc that is memoized after being accessed for the first time
69
68
  # @return [Ryo::Memo]
70
- # Returns an instance of {Ryo::Memo Ryo::Memo}.
69
+ # Returns an instance of {Ryo::Memo Ryo::Memo}
71
70
  def self.memo(&b)
72
71
  Ryo::Memo.new(&b)
73
72
  end
@@ -76,36 +75,32 @@ module Ryo
76
75
  end
77
76
 
78
77
  ##
79
- # Creates a Ryo object by recursively walking a Hash object.
78
+ # Creates a Ryo object by recursively walking a Hash object
80
79
  #
81
80
  # @param props (see Ryo::Builder.build)
82
81
  # @param prototype (see Ryo::Builder.build)
83
- #
84
82
  # @return [Ryo::Object]
85
- # Returns an instance of {Ryo::Object Ryo::Object}.
83
+ # Returns an instance of {Ryo::Object Ryo::Object}
86
84
  def self.from(props, prototype = nil)
87
85
  Ryo::Object.from(props, prototype)
88
86
  end
89
87
 
90
88
  ##
91
- # Returns the prototype of self, or "nil" if self has no prototype.
92
- #
93
89
  # @return [<Ryo::Object, Ryo::BasicObject>, nil]
90
+ # Returns the prototype of self, or nil if self has no prototype
94
91
  def __proto__
95
92
  @_proto
96
93
  end
97
94
 
98
95
  ##
96
+ # @note
97
+ # This method will first look for a property on self,
98
+ # and if it is not found then it will forward the query
99
+ # onto `Ryo#__proto__`
99
100
  # @param [String] property
100
- # A property name.
101
- #
101
+ # The name of a property
102
102
  # @return [<Object, BasicObject>, nil]
103
- # Returns the value at **property**, or nil.
104
- #
105
- # @note
106
- # This method will first try to read **property** from self, and if
107
- # it is not found on self the chain of prototypes will be traversed
108
- # through instead.
103
+ # Returns the property's value, or nil
109
104
  def [](property)
110
105
  property = property.to_s
111
106
  if Ryo.property?(self, property)
@@ -118,14 +113,11 @@ module Ryo
118
113
  end
119
114
 
120
115
  ##
121
- # Assigns a property to self.
116
+ # Assign a property
122
117
  #
123
118
  # @param [String] property
124
- # A property name.
125
- #
119
+ # The name of a property
126
120
  # @param [<Object,BasicObject>] value
127
- # The value.
128
- #
129
121
  # @return [void]
130
122
  def []=(property, value)
131
123
  Ryo.define_property(self, property.to_s, value)
@@ -133,10 +125,8 @@ module Ryo
133
125
 
134
126
  ##
135
127
  # @param [<Ryo::Object, Ryo::BasicObject>, Hash, #to_h] other
136
- # An object to compare against.
137
- #
138
128
  # @return [Boolean]
139
- # Returns true **other** is equal to self.
129
+ # Returns true **other** is equal to self
140
130
  def ==(other)
141
131
  if Ryo.ryo?(other)
142
132
  @_table == Ryo.table_of(other)
@@ -150,14 +140,14 @@ module Ryo
150
140
 
151
141
  ##
152
142
  # @return [String]
153
- # Returns a String representation of a Ryo object.
143
+ # Returns a String representation of a Ryo object
154
144
  def inspect
155
145
  Ryo.inspect_object(self)
156
146
  end
157
147
 
158
148
  ##
159
149
  # @return [Hash]
160
- # Returns the hash table used by a Ryo object.
150
+ # Returns the lookup table of a Ryo object
161
151
  def to_h
162
152
  Ryo.table_of(self, recursive: true)
163
153
  end
@@ -200,9 +190,8 @@ end
200
190
  ##
201
191
  # @param props (see Ryo::Builder.build)
202
192
  # @param prototype (see Ryo::Builder.build)
203
- #
204
193
  # @return [Ryo::Object]
205
- # Returns a Ryo object.
194
+ # Returns a Ryo object
206
195
  def Ryo(props, prototype = nil)
207
196
  Ryo::Object.create(props, prototype)
208
197
  end
data/ryo.rb.gemspec CHANGED
@@ -19,4 +19,5 @@ Gem::Specification.new do |gem|
19
19
  gem.add_development_dependency "rubocop-rspec", "~> 2.12"
20
20
  gem.add_development_dependency "standard", "~> 1.9"
21
21
  gem.add_development_dependency "test-cmd.rb", "~> 0.12"
22
+ gem.add_development_dependency "rake", "~> 13.2"
22
23
  end
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env ruby
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require_relative "setup"
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env ruby
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require_relative "setup"
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env ruby
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require_relative "setup"
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env ruby
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require_relative "setup"
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env ruby
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require_relative "setup"
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "setup"
5
+ require "ryo"
6
+
7
+ person = Ryo.from({
8
+ name: "John",
9
+ age: 30,
10
+ address: {
11
+ street: "123 Main St",
12
+ city: "Anytown",
13
+ state: "AS",
14
+ zip: 12345
15
+ }
16
+ })
17
+ p [person.name, person.age, person.address.city]
18
+
19
+ ##
20
+ # ["John", 30, "Anytown"]
@@ -1,17 +1,18 @@
1
+ #!/usr/bin/env ruby
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require_relative "setup"
4
5
  require "ryo"
5
6
 
6
7
  points = Ryo.from([
7
- {x: {to_i: 2}},
8
+ {x: 2},
8
9
  "foobar",
9
- {y: {to_i: 4}}
10
+ {y: 4}
10
11
  ])
11
12
 
12
- p points[0].x.to_i
13
+ p points[0].x
13
14
  p points[1]
14
- p points[2].y.to_i
15
+ p points[2].y
15
16
 
16
17
  ##
17
18
  # 2
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env ruby
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require_relative "setup"
@@ -5,10 +6,9 @@ require "ryo"
5
6
  require "ostruct"
6
7
 
7
8
  point = Ryo.from(
8
- OpenStruct.new(x: {to_i: 5}),
9
- Ryo.from(y: {to_i: 10})
9
+ OpenStruct.new(x: 5, y: 10)
10
10
  )
11
- p [point.x.to_i, point.y.to_i]
11
+ p [point.x, point.y]
12
12
 
13
13
  ##
14
14
  # [5, 10]
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env ruby
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require_relative "setup"
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env ruby
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require_relative "setup"
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env ruby
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require_relative "setup"
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env ruby
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require_relative "setup"
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env ruby
1
2
  require_relative "setup"
2
3
  require "ryo"
3
4
 
data/share/ryo.rb/NEWS ADDED
@@ -0,0 +1,11 @@
1
+ # -*- mode: org -*-
2
+
3
+ * vNEXT
4
+
5
+ **** Automatically require ~ryo/json~, ~ryo/yaml~
6
+ Both files are now required in ~lib/ryo.rb~, so they can be used
7
+ without requiring them separately
8
+
9
+ **** ~Ryo.delete!~ => ~Ryo.delete~
10
+ Other than the rename: ~Ryo.delete~ accepts an ~ancestors~ option,
11
+ and by default traverses the entire prototype chain
data/spec/readme_spec.rb CHANGED
@@ -5,7 +5,7 @@ require "test-cmd"
5
5
 
6
6
  RSpec.describe "README.md examples" do
7
7
  run_example = ->(file) do
8
- cmd("ruby", "share/ryo.rb/examples/#{file}")
8
+ cmd("ruby", "share/examples/ryo.rb/#{file}")
9
9
  end
10
10
 
11
11
  subject do
@@ -39,7 +39,7 @@ RSpec.describe "README.md examples" do
39
39
 
40
40
  context "when given 3.0_recursion_ryo_from.rb" do
41
41
  let(:file) { "3.0_recursion_ryo_from.rb" }
42
- it { is_expected.to eq("[0, 10]") }
42
+ it { is_expected.to eq("[\"John\", 30, \"Anytown\"]") }
43
43
  end
44
44
 
45
45
  context "when given 3.1_recursion_ryo_from_with_array.rb" do
@@ -29,7 +29,7 @@ RSpec.describe Ryo::Enumerable do
29
29
  end
30
30
 
31
31
  context "when verifying the map operation returns a new object" do
32
- subject { Ryo.kernel(:equal?).bind_call(point_b, point_c) }
32
+ subject { Module.instance_method(:equal?).bind_call(point_b, point_c) }
33
33
  it { is_expected.to be(false) }
34
34
  end
35
35
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "setup"
4
- require "ryo/json"
4
+ require "json"
5
5
  require "fileutils"
6
6
 
7
7
  RSpec.describe Ryo::JSON do
@@ -47,7 +47,7 @@ RSpec.describe Ryo::Keywords do
47
47
  context "when a property is deleted from point_b" do
48
48
  subject { point_b.x }
49
49
  before { Ryo.delete(point_b, "x") }
50
- it { is_expected.to eq(0) }
50
+ it { is_expected.to eq(nil) }
51
51
  end
52
52
 
53
53
  context "when a property is deleted from both point_a / point_b" do
@@ -39,7 +39,7 @@ RSpec.describe "Prototypes" do
39
39
  subject { node_2.name }
40
40
  let(:node_1) { Ryo({name: "Node 1"}, root) }
41
41
  before { Ryo.delete(node_1, "name") }
42
- it { is_expected.to eq("root") }
42
+ it { is_expected.to eq(nil) }
43
43
  end
44
44
  end
45
45
  end
@@ -170,6 +170,14 @@ RSpec.describe Ryo::Reflect do
170
170
  it { expect(table["point"]["point"]).to be_instance_of(Hash) }
171
171
  it { is_expected.to eq("point" => {"point" => {"x" => 1, "y" => 1}}) }
172
172
  end
173
+
174
+ context "when a Ryo object references an Array" do
175
+ let(:ryo) { Ryo(points: [Ryo(x: 1, y: 1)]) }
176
+ it { expect(table).to be_instance_of(Hash) }
177
+ it { expect(table["points"]).to be_instance_of(Array) }
178
+ it { expect(table["points"][0]).to be_instance_of(Hash) }
179
+ it { is_expected.to eq("points" => [{"x" => 1, "y" => 1}]) }
180
+ end
173
181
  end
174
182
  end
175
183
  end
data/spec/ryo_spec.rb CHANGED
@@ -113,7 +113,7 @@ RSpec.describe Ryo do
113
113
  end
114
114
 
115
115
  context "when verifying the source and duplicate are distinct objects" do
116
- subject { Ryo.kernel(:equal?).bind_call(point_c, dup) }
116
+ subject { Module.instance_method(:equal?).bind_call(point_c, dup) }
117
117
  it { is_expected.to eq(false) }
118
118
  end
119
119
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "setup"
4
- require "ryo/yaml"
4
+ require "yaml"
5
5
  require "fileutils"
6
6
 
7
7
  RSpec.describe Ryo::YAML do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ryo.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.5.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - '0x1eef'
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-20 00:00:00.000000000 Z
11
+ date: 2025-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: yard
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.12'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '13.2'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '13.2'
97
111
  description: Ryo implements prototype-based inheritance, in Ruby
98
112
  email:
99
113
  - 0x1eef@protonmail.com
@@ -108,7 +122,6 @@ files:
108
122
  - ".rubocop.yml"
109
123
  - ".yardopts"
110
124
  - Gemfile
111
- - LICENSE
112
125
  - README.md
113
126
  - Rakefile.rb
114
127
  - lib/ryo.rb
@@ -121,23 +134,26 @@ files:
121
134
  - lib/ryo/memo.rb
122
135
  - lib/ryo/object.rb
123
136
  - lib/ryo/reflect.rb
137
+ - lib/ryo/utils.rb
124
138
  - lib/ryo/version.rb
125
139
  - lib/ryo/yaml.rb
126
140
  - ryo.rb.gemspec
127
- - share/ryo.rb/examples/1.0_prototypes_point_object.rb
128
- - share/ryo.rb/examples/1.1_prototypes_ryo_fn.rb
129
- - share/ryo.rb/examples/2.0_iteration_each.rb
130
- - share/ryo.rb/examples/2.1_iteration_map.rb
131
- - share/ryo.rb/examples/2.2_iteration_ancestors.rb
132
- - share/ryo.rb/examples/3.0_recursion_ryo_from.rb
133
- - share/ryo.rb/examples/3.1_recursion_ryo_from_with_array.rb
134
- - share/ryo.rb/examples/3.2_recursion_ryo_from_with_openstruct.rb
135
- - share/ryo.rb/examples/4.0_basicobject_ryo_basicobject.rb
136
- - share/ryo.rb/examples/4.1_basicobject_ryo_basicobject_from.rb
137
- - share/ryo.rb/examples/5_collisions_resolution_strategy.rb
138
- - share/ryo.rb/examples/6_beyond_hash_objects.rb
139
- - share/ryo.rb/examples/7_ryo_memo.rb
140
- - share/ryo.rb/examples/setup.rb
141
+ - share/examples/ryo.rb/1.0_prototypes_point_object.rb
142
+ - share/examples/ryo.rb/1.1_prototypes_ryo_fn.rb
143
+ - share/examples/ryo.rb/2.0_iteration_each.rb
144
+ - share/examples/ryo.rb/2.1_iteration_map.rb
145
+ - share/examples/ryo.rb/2.2_iteration_ancestors.rb
146
+ - share/examples/ryo.rb/3.0_recursion_ryo_from.rb
147
+ - share/examples/ryo.rb/3.1_recursion_ryo_from_with_array.rb
148
+ - share/examples/ryo.rb/3.2_recursion_ryo_from_with_openstruct.rb
149
+ - share/examples/ryo.rb/4.0_basicobject_ryo_basicobject.rb
150
+ - share/examples/ryo.rb/4.1_basicobject_ryo_basicobject_from.rb
151
+ - share/examples/ryo.rb/5_collisions_resolution_strategy.rb
152
+ - share/examples/ryo.rb/6_beyond_hash_objects.rb
153
+ - share/examples/ryo.rb/7_ryo_memo.rb
154
+ - share/examples/ryo.rb/setup.rb
155
+ - share/ryo.rb/LICENSE
156
+ - share/ryo.rb/NEWS
141
157
  - spec/readme_spec.rb
142
158
  - spec/ryo_basic_object_spec.rb
143
159
  - spec/ryo_enumerable_spec.rb
@@ -168,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
184
  - !ruby/object:Gem::Version
169
185
  version: '0'
170
186
  requirements: []
171
- rubygems_version: 3.5.9
187
+ rubygems_version: 3.5.23
172
188
  signing_key:
173
189
  specification_version: 4
174
190
  summary: Ryo implements prototype-based inheritance, in Ruby
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "setup"
4
- require "ryo"
5
-
6
- point = Ryo.from({
7
- x: {to_i: 0},
8
- y: {to_i: 10}
9
- })
10
- p [point.x.to_i, point.y.to_i]
11
-
12
- ##
13
- # [0, 10]
File without changes