ryo.rb 0.4.7 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0dab9ce575cc86bc7fc740dc72d1a1c416a22d36ed8806b86e1c7f60c0b46f5b
4
- data.tar.gz: 403f51fb967e4c745461a61092984f78de8fac139465da0442cd30dea66c807d
3
+ metadata.gz: 4d4a31df7a8e4862600d2e3072df9320d95cdd805fdef5028cd1c6154a9786c2
4
+ data.tar.gz: 862aa59d0f09c4ebcabb9c5552f390dc8456a5964601c48d866a84a01e871443
5
5
  SHA512:
6
- metadata.gz: dcac875bbd985395ffa37b1b3c48e9f52ebd11d36514faf75e18134530fc2599fbac437114d3d9c2530a66aec810cc7de8904355467a9854d9a9b4f80f2c63f6
7
- data.tar.gz: bbb67ac56137b8989b8c94f82b20c887d3914d7218170ded3688e8f53251d2ef1808af4a143e469c374951031a1ab40b3f8ed6cf0ce084ee72f078ad2022446f
6
+ metadata.gz: 57bab86f4003fb0aa40c43fa2fc41d335b26ead6c99522d97227f25279b5f45330c7fc9edf66b4682508d4cf13593be6d1ce55ab8507263cad75fa99605651c0
7
+ data.tar.gz: 384411a195dbd7699dfa9f8b3a253588e477b28b04210c3a8452285f47778d149f090750b352de9bf9e95f19fb679127062b2fcce90aac5d0bc99224f452cf3c
data/README.md CHANGED
@@ -2,13 +2,6 @@
2
2
 
3
3
  Ryo implements prototype-based inheritance, in Ruby.
4
4
 
5
- Ryo's implementation of prototype-based inheritance offers
6
- a flexible approach for establishing object relationships,
7
- and building configuration objects. Ryo can also act as a
8
- recursive OpenStruct alternative. JavaScript's implementation of
9
- prototype-based inheritance served as a reference point
10
- for Ryo's implementation.
11
-
12
5
  ## Examples
13
6
 
14
7
  ### Prototypes
@@ -55,21 +48,19 @@ p point.multiply.call(2)
55
48
  # [10, 20]
56
49
  ```
57
50
 
58
- #### Ryo.lazy
51
+ #### Ryo.memo
59
52
 
60
- The following example demonstrates a lazy Ryo value.
61
- [`Ryo.lazy`](https://0x1eef.github.io/x/ryo.rb/Ryo.html#lazy-class_method)
62
- creates a lazy value that is not evaluated until a property is accessed
63
- for the first time. It is similar to a Ryo function but it does not require
64
- that the `#call` method be used, and after the property is accessed for the
65
- first time the lazy value is replaced by the evaluated value:
53
+ The following example demonstrates
54
+ [`Ryo.memo`](https://0x1eef.github.io/x/ryo.rb/Ryo.html#memo-class_method).
55
+ `Ryo.memo` returns a value that becomes memoized after a property is
56
+ accessed for the first time. It is similar to a Ryo function:
66
57
 
67
58
  ```ruby
68
59
  require "ryo"
69
60
 
70
- point_x = Ryo(x: Ryo.lazy { 5 })
71
- point_y = Ryo({y: Ryo.lazy { 10 }}, point_x)
72
- point = Ryo({sum: Ryo.lazy { x + y }}, point_y)
61
+ point_x = Ryo(x: Ryo.memo { 5 })
62
+ point_y = Ryo({y: Ryo.memo { 10 }}, point_x)
63
+ point = Ryo({sum: Ryo.memo { x + y }}, point_y)
73
64
  print "point.x = ", point.x, "\n"
74
65
  print "point.y = ", point.y, "\n"
75
66
  print "point.sum = ", point.sum, "\n"
@@ -310,7 +301,7 @@ p ryo.then { 34 } # => 34
310
301
  #### Duck typing
311
302
 
312
303
  The documentation has used simple terms to describe the objects that Ryo works
313
- with: Hash and Array objects. But actually, Ryo uses duck typing, so any object
304
+ with: Hash and Array objects. But in reality, Ryo uses duck typing, so any object
314
305
  that implements `#each_pair` can be treated as a Hash object, and any object that
315
306
  implements `#each` can be treated as an Array object. Note that only
316
307
  [Ryo.from](https://0x1eef.github.io/x/ryo.rb/Ryo.html#from-class_method),
@@ -342,32 +333,19 @@ p point.x # => 5
342
333
  p point.y # => 10
343
334
  ```
344
335
 
345
- ## Sources
346
-
347
- * [Source code (GitHub)](https://github.com/0x1eef/ryo.rb#readme)
348
- * [Source code (GitLab)](https://gitlab.com/0x1eef/ryo.rb#about)
349
-
350
336
  ## <a id='install'>Install</a>
351
337
 
352
- **Git**
353
-
354
- Ryo is distributed as a RubyGem through its git repositories. <br>
355
- [GitHub](https://github.com/0x1eef/ryo.rb),
356
- and
357
- [GitLab](https://gitlab.com/0x1eef/ryo.rb)
358
- are available as sources.
359
-
360
- ```ruby
361
- # Gemfile
362
- gem "ryo.rb", github: "0x1eef/ryo.rb", tag: "v0.4.7"
363
- ```
364
-
365
338
  **Rubygems.org**
366
339
 
367
- Ryo can also be installed via rubygems.org.
340
+ Ryo can be installed via rubygems.org.
368
341
 
369
342
  gem install ryo.rb
370
343
 
344
+ ## Sources
345
+
346
+ * [GitHub](https://github.com/0x1eef/ryo.rb#readme)
347
+ * [GitLab](https://gitlab.com/0x1eef/ryo.rb#about)
348
+
371
349
  ## Thanks
372
350
 
373
351
  Thanks to
data/lib/ryo/json.rb ADDED
@@ -0,0 +1,41 @@
1
+ ##
2
+ # The {Ryo::JSON Ryo::JSON} module provides a number of methods
3
+ # for coercing JSON data into a Ryo object. It must be required
4
+ # separately to Ryo (ie: require "ryo/json"), and the methods of
5
+ # this module are then available on the {Ryo Ryo} module.
6
+ module Ryo::JSON
7
+ require "json"
8
+ extend self
9
+
10
+ ##
11
+ # @param [String] path
12
+ # The path to a JSON file.
13
+ #
14
+ # @param [Ryo] object
15
+ # {Ryo::Object Ryo::Object}, or {Ryo::BasicObject Ryo::BasicObject}.
16
+ # Defaults to {Ryo::Object Ryo::Object}.
17
+ #
18
+ # @raise [SystemCallError]
19
+ # Might raise a number of Errno exceptions.
20
+ #
21
+ # @return [Ryo::Object, Ryo::BasicObject]
22
+ # Returns a Ryo object.
23
+ def from_json_file(path, object: Ryo::Object)
24
+ from_json File.binread(path), object:
25
+ end
26
+
27
+ ##
28
+ # @param [String] blob
29
+ # A blob of JSON.
30
+ #
31
+ # @param [Ryo] object
32
+ # {Ryo::Object Ryo::Object}, or {Ryo::BasicObject Ryo::BasicObject}.
33
+ # Defaults to {Ryo::Object Ryo::Object}.
34
+ #
35
+ # @return (see Ryo::JSON#from_json_file)
36
+ def from_json(blob, object: Ryo::Object)
37
+ object.from JSON.parse(blob)
38
+ end
39
+
40
+ Ryo.extend(self)
41
+ end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class Ryo::Lazy < Ryo::Function
3
+ class Ryo::Memo < Ryo::Function
4
4
  end
data/lib/ryo/reflect.rb CHANGED
@@ -251,10 +251,11 @@ module Ryo::Reflect
251
251
  #
252
252
  # @return [Boolean]
253
253
  # Returns true when the given object is an instance
254
- # of {Ryo::Lazy Ryo::Lazy}.
255
- def lazy?(obj)
256
- Ryo::Lazy === obj
254
+ # of {Ryo::Memo Ryo::Memo}.
255
+ def memo?(obj)
256
+ Ryo::Memo === obj
257
257
  end
258
+ alias_method :lazy?, :memo?
258
259
 
259
260
  ##
260
261
  # @example
data/lib/ryo/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ryo
4
- VERSION = "0.4.7"
4
+ VERSION = "0.5.1"
5
5
  end
data/lib/ryo.rb CHANGED
@@ -21,7 +21,7 @@ module Ryo
21
21
  require_relative "ryo/basic_object"
22
22
  require_relative "ryo/object"
23
23
  require_relative "ryo/function"
24
- require_relative "ryo/lazy"
24
+ require_relative "ryo/memo"
25
25
  require_relative "ryo/enumerable"
26
26
 
27
27
  extend Ryo::Reflect
@@ -61,15 +61,18 @@ module Ryo
61
61
  end
62
62
 
63
63
  ##
64
- # Creates a lazy Ryo value.
64
+ # Creates a memoized Ryo value.
65
65
  #
66
66
  # @param [Proc] b
67
- # A proc that is evaluated when a property is first accessed.
67
+ # A Proc that is memoized after being accessed for the first time.
68
68
  #
69
- # @return [Ryo::Lazy]
70
- # Returns an instance of {Ryo::Lazy Ryo::Lazy}.
71
- def self.lazy(&b)
72
- Ryo::Lazy.new(&b)
69
+ # @return [Ryo::Memo]
70
+ # Returns an instance of {Ryo::Memo Ryo::Memo}.
71
+ def self.memo(&b)
72
+ Ryo::Memo.new(&b)
73
+ end
74
+ class << Ryo
75
+ alias_method :lazy, :memo
73
76
  end
74
77
 
75
78
  ##
@@ -107,7 +110,7 @@ module Ryo
107
110
  property = property.to_s
108
111
  if Ryo.property?(self, property)
109
112
  v = @_table[property]
110
- Ryo.lazy?(v) ? self[property] = v.call : v
113
+ Ryo.memo?(v) ? self[property] = v.call : v
111
114
  else
112
115
  return unless @_proto
113
116
  Ryo.call_method(@_proto, property)
data/spec/readme_spec.rb CHANGED
@@ -72,8 +72,8 @@ RSpec.describe "README.md examples" do
72
72
  it { is_expected.to eq("5\n10") }
73
73
  end
74
74
 
75
- context "when given 7_ryo_lazy.rb" do
76
- let(:file) { "7_ryo_lazy.rb" }
75
+ context "when given 7_ryo_memo.rb" do
76
+ let(:file) { "7_ryo_memo.rb" }
77
77
  it { is_expected.to eq("point.x = 5\npoint.y = 10\npoint.sum = 15") }
78
78
  end
79
79
  end
@@ -66,10 +66,10 @@ RSpec.describe Ryo::BasicObject do
66
66
  it { expect(h).to eq({"name" => "ford", "wheels" => {"quantity" => 4}}) }
67
67
 
68
68
  context "when given to Hash#merge" do
69
- let(:car) { Ryo(name: "ford") }
70
69
  subject { {}.merge(car) }
70
+ let(:car) { Ryo(name: "ford") }
71
71
  it { is_expected.to be_instance_of(Hash) }
72
- it { is_expected.to eq({"name" => "ford"})}
72
+ it { is_expected.to eq({"name" => "ford"}) }
73
73
  end
74
74
  end
75
75
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "setup"
4
+ require "ryo/json"
5
+ require "fileutils"
6
+
7
+ RSpec.describe Ryo::JSON do
8
+ describe ".from_json_file" do
9
+ subject(:ryo) { described_class.from_json_file(path, object:) }
10
+ before { File.binwrite path, JSON.dump(x: 20, y: 40) }
11
+ after { FileUtils.rm(path) }
12
+ let(:path) { File.join(__dir__, "test.json") }
13
+
14
+ context "with Ryo::Object" do
15
+ let(:object) { Ryo::Object }
16
+ it { is_expected.to be_instance_of(Ryo::Object) }
17
+ it { is_expected.to eq("x" => 20, "y" => 40) }
18
+ end
19
+
20
+ context "with Ryo::BasicObject" do
21
+ let(:object) { Ryo::BasicObject }
22
+ it { expect(Ryo::BasicObject === ryo).to be(true) }
23
+ it { is_expected.to eq("x" => 20, "y" => 40) }
24
+ end
25
+ end
26
+ end
@@ -61,10 +61,10 @@ RSpec.describe "Ryo objects" do
61
61
  it { expect(h).to eq({"name" => "ford", "wheels" => {"quantity" => 4}}) }
62
62
 
63
63
  context "when given to Hash#merge" do
64
- let(:car) { Ryo(name: "ford") }
65
64
  subject { {}.merge(car) }
65
+ let(:car) { Ryo(name: "ford") }
66
66
  it { is_expected.to be_instance_of(Hash) }
67
- it { is_expected.to eq({"name" => "ford"})}
67
+ it { is_expected.to eq({"name" => "ford"}) }
68
68
  end
69
69
  end
70
70
 
data/spec/ryo_spec.rb CHANGED
@@ -127,4 +127,20 @@ RSpec.describe Ryo do
127
127
  it { is_expected.to eq(true) }
128
128
  end
129
129
  end
130
+
131
+ describe ".memo" do
132
+ let(:point) do
133
+ Ryo(x: Ryo.memo { "5".dup }, y: Ryo.memo { "10".dup })
134
+ end
135
+
136
+ it "returns a value" do
137
+ expect(point.x).to eq("5")
138
+ expect(point.y).to eq("10")
139
+ end
140
+
141
+ it "memoizes a value" do
142
+ expect(point.x).to equal(point.x)
143
+ expect(point.y).to equal(point.y)
144
+ end
145
+ end
130
146
  end
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.4.7
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - '0x1eef'
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-01 00:00:00.000000000 Z
11
+ date: 2024-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: yard
@@ -116,8 +116,9 @@ files:
116
116
  - lib/ryo/builder.rb
117
117
  - lib/ryo/enumerable.rb
118
118
  - lib/ryo/function.rb
119
+ - lib/ryo/json.rb
119
120
  - lib/ryo/keywords.rb
120
- - lib/ryo/lazy.rb
121
+ - lib/ryo/memo.rb
121
122
  - lib/ryo/object.rb
122
123
  - lib/ryo/reflect.rb
123
124
  - lib/ryo/version.rb
@@ -134,11 +135,12 @@ files:
134
135
  - share/ryo.rb/examples/4.1_basicobject_ryo_basicobject_from.rb
135
136
  - share/ryo.rb/examples/5_collisions_resolution_strategy.rb
136
137
  - share/ryo.rb/examples/6_beyond_hash_objects.rb
137
- - share/ryo.rb/examples/7_ryo_lazy.rb
138
+ - share/ryo.rb/examples/7_ryo_memo.rb
138
139
  - share/ryo.rb/examples/setup.rb
139
140
  - spec/readme_spec.rb
140
141
  - spec/ryo_basic_object_spec.rb
141
142
  - spec/ryo_enumerable_spec.rb
143
+ - spec/ryo_json_spec.rb
142
144
  - spec/ryo_keywords_spec.rb
143
145
  - spec/ryo_object_spec.rb
144
146
  - spec/ryo_prototypes_spec.rb