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 +4 -4
- data/README.md +15 -37
- data/lib/ryo/json.rb +41 -0
- data/lib/ryo/{lazy.rb → memo.rb} +1 -1
- data/lib/ryo/reflect.rb +4 -3
- data/lib/ryo/version.rb +1 -1
- data/lib/ryo.rb +11 -8
- data/spec/readme_spec.rb +2 -2
- data/spec/ryo_basic_object_spec.rb +2 -2
- data/spec/ryo_json_spec.rb +26 -0
- data/spec/ryo_object_spec.rb +2 -2
- data/spec/ryo_spec.rb +16 -0
- metadata +6 -4
- /data/share/ryo.rb/examples/{7_ryo_lazy.rb → 7_ryo_memo.rb} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4d4a31df7a8e4862600d2e3072df9320d95cdd805fdef5028cd1c6154a9786c2
|
4
|
+
data.tar.gz: 862aa59d0f09c4ebcabb9c5552f390dc8456a5964601c48d866a84a01e871443
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
51
|
+
#### Ryo.memo
|
59
52
|
|
60
|
-
The following example demonstrates
|
61
|
-
[`Ryo.
|
62
|
-
|
63
|
-
for the first time. It is similar to a Ryo function
|
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.
|
71
|
-
point_y = Ryo({y: Ryo.
|
72
|
-
point = Ryo({sum: Ryo.
|
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
|
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
|
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
|
data/lib/ryo/{lazy.rb → memo.rb}
RENAMED
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::
|
255
|
-
def
|
256
|
-
Ryo::
|
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
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/
|
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
|
64
|
+
# Creates a memoized Ryo value.
|
65
65
|
#
|
66
66
|
# @param [Proc] b
|
67
|
-
# A
|
67
|
+
# A Proc that is memoized after being accessed for the first time.
|
68
68
|
#
|
69
|
-
# @return [Ryo::
|
70
|
-
# Returns an instance of {Ryo::
|
71
|
-
def self.
|
72
|
-
Ryo::
|
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.
|
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
|
76
|
-
let(:file) { "
|
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
|
data/spec/ryo_object_spec.rb
CHANGED
@@ -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
|
+
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-
|
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/
|
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/
|
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
|
File without changes
|