persistent_open_struct 0.0.1
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 +7 -0
- data/.gitignore +22 -0
- data/.travis.yml +4 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +136 -0
- data/Rakefile +10 -0
- data/benchmark/benchmark.rb +83 -0
- data/lib/persistent_open_struct.rb +17 -0
- data/lib/persistent_open_struct/version.rb +5 -0
- data/persistent_open_struct.gemspec +25 -0
- data/test/test_helper.rb +2 -0
- data/test/test_persistent_open_struct.rb +150 -0
- metadata +114 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3ef836525502250c550a58f6988dcd6285d93337
|
4
|
+
data.tar.gz: fff2627187409c4c5109de37858a644771a722d3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6bd65c8ea98bcbfec8b7e0fea83a8615c6a0be59c3c77ff08326d971f278ea7b97ef7ce2a932d64e1efc4d03075e6ff85c9a026a264220a6809e850e5e8f7ea2
|
7
|
+
data.tar.gz: ceabca536ad1a1015eeb8d409b072cf4386e9b270ff4548d6633f95526039aed13789ddc0f0fa1d7a419908b6e7c89bdffedd74d05b1e6c438f32e25595babcb
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 amcaplan
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
[](http://badge.fury.io/rb/persistent_open_struct)
|
2
|
+

|
3
|
+
|
4
|
+
# PersistentOpenStruct
|
5
|
+
|
6
|
+
Are you inserting data in the same format into OpenStruct again and again?
|
7
|
+
Wishing OpenStruct wouldn't have to define a new singleton method on each
|
8
|
+
individual object? Here is your solution!
|
9
|
+
|
10
|
+
PersistentOpenStruct defines methods on the class, so as long as you keep using
|
11
|
+
the same keys, no new methods will be defined. The class quickly learns the
|
12
|
+
shape of your data, so you can use it with minimal overhead. (Though of course
|
13
|
+
it's still not as fast as doing the work of defining a full-fledged class.)
|
14
|
+
|
15
|
+
It obeys the entire interface of OpenStruct, so you can insert it into your code
|
16
|
+
without problem! (Unless you're using `OpenStruct#delete_field` for some reason;
|
17
|
+
PersistentOpenStruct refuses to undefine the methods it defines.)
|
18
|
+
|
19
|
+
This gives a noticeable performance boost. Here are the results of the benchmark
|
20
|
+
found at
|
21
|
+
[`benchmark/benchmark.rb`](http://github.com/amcaplan/persistent_open_struct/blob/master/benchmark/benchmark.rb);
|
22
|
+
included are
|
23
|
+
results for [`OpenFastStruct`](http://github.com/arturoherrero/ofstruct) as
|
24
|
+
well, to get a sense of alternative solutions.
|
25
|
+
|
26
|
+
``` ruby
|
27
|
+
require 'benchmark/ips'
|
28
|
+
require 'ostruct'
|
29
|
+
require_relative '../lib/persistent_open_struct'
|
30
|
+
|
31
|
+
Benchmark.ips do |x|
|
32
|
+
input_hash = { foo: :bar }
|
33
|
+
x.report('OpenStruct') do
|
34
|
+
OpenStruct.new(input_hash)
|
35
|
+
end
|
36
|
+
|
37
|
+
x.report('PersistentOpenStruct') do
|
38
|
+
PersistentOpenStruct.new(input_hash)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
puts "\n\n"
|
43
|
+
|
44
|
+
Benchmark.ips do |x|
|
45
|
+
x.report('OpenStruct') do
|
46
|
+
OpenStruct.new.foo = :bar
|
47
|
+
end
|
48
|
+
|
49
|
+
x.report('PersistentOpenStruct') do
|
50
|
+
PersistentOpenStruct.new.foo = :bar
|
51
|
+
end
|
52
|
+
end
|
53
|
+
```
|
54
|
+
And the results:
|
55
|
+
```
|
56
|
+
$ ruby benchmark/benchmark.rb
|
57
|
+
Initialization benchmark
|
58
|
+
|
59
|
+
Calculating -------------------------------------
|
60
|
+
OpenStruct 17.082k i/100ms
|
61
|
+
PersistentOpenStruct 61.316k i/100ms
|
62
|
+
OpenFastStruct 62.589k i/100ms
|
63
|
+
RegularClass 122.018k i/100ms
|
64
|
+
-------------------------------------------------
|
65
|
+
OpenStruct 192.534k (± 3.4%) i/s - 973.674k
|
66
|
+
PersistentOpenStruct 955.081k (± 3.1%) i/s - 4.783M
|
67
|
+
OpenFastStruct 980.760k (± 4.2%) i/s - 4.945M
|
68
|
+
RegularClass 3.615M (± 4.4%) i/s - 18.059M
|
69
|
+
|
70
|
+
|
71
|
+
Assignment Benchmark
|
72
|
+
|
73
|
+
Calculating -------------------------------------
|
74
|
+
OpenStruct 119.904k i/100ms
|
75
|
+
PersistentOpenStruct 120.998k i/100ms
|
76
|
+
OpenFastStruct 67.418k i/100ms
|
77
|
+
RegularClass 152.935k i/100ms
|
78
|
+
-------------------------------------------------
|
79
|
+
OpenStruct 3.707M (± 4.7%) i/s - 18.585M
|
80
|
+
PersistentOpenStruct 3.753M (± 4.0%) i/s - 18.755M
|
81
|
+
OpenFastStruct 1.133M (± 2.6%) i/s - 5.731M
|
82
|
+
RegularClass 9.155M (± 4.8%) i/s - 45.728M
|
83
|
+
|
84
|
+
|
85
|
+
Access Benchmark
|
86
|
+
|
87
|
+
Calculating -------------------------------------
|
88
|
+
OpenStruct 134.887k i/100ms
|
89
|
+
PersistentOpenStruct 134.239k i/100ms
|
90
|
+
OpenFastStruct 120.480k i/100ms
|
91
|
+
RegularClass 134.040k i/100ms
|
92
|
+
-------------------------------------------------
|
93
|
+
OpenStruct 5.558M (± 3.2%) i/s - 27.787M
|
94
|
+
PersistentOpenStruct 5.531M (± 4.3%) i/s - 27.653M
|
95
|
+
OpenFastStruct 3.996M (± 4.7%) i/s - 20.000M
|
96
|
+
RegularClass 5.562M (± 3.5%) i/s - 27.880M
|
97
|
+
```
|
98
|
+
|
99
|
+
## Installation
|
100
|
+
|
101
|
+
Add this line to your application's Gemfile:
|
102
|
+
|
103
|
+
gem 'persistent_open_struct'
|
104
|
+
|
105
|
+
And then execute:
|
106
|
+
|
107
|
+
$ bundle
|
108
|
+
|
109
|
+
Or install it yourself as:
|
110
|
+
|
111
|
+
$ gem install persistent_open_struct
|
112
|
+
|
113
|
+
## Usage
|
114
|
+
Note: requires Ruby 2.1.0 or above.
|
115
|
+
|
116
|
+
``` ruby
|
117
|
+
class MyDataStructure < PersistentOpenStruct
|
118
|
+
end
|
119
|
+
|
120
|
+
datum1 = MyDataStructure.new(foo: :bar)
|
121
|
+
|
122
|
+
datum2 = MyDataStructure.new
|
123
|
+
datum2.respond_to?(:baz) #=> false
|
124
|
+
datum2.respond_to?(:foo) #=> true
|
125
|
+
```
|
126
|
+
|
127
|
+
## Contributing
|
128
|
+
|
129
|
+
1. Fork it ( https://github.com/[my-github-username]/persistent_open_struct/fork )
|
130
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
131
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
132
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
133
|
+
5. Create a new Pull Request
|
134
|
+
|
135
|
+
Pull requests will not be considered without tests of whatever you seek to
|
136
|
+
change, unless you are submitting a performance improvement.
|
data/Rakefile
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'benchmark/ips'
|
2
|
+
require 'ostruct'
|
3
|
+
require 'ofstruct'
|
4
|
+
require_relative '../lib/persistent_open_struct'
|
5
|
+
|
6
|
+
class RegularClass
|
7
|
+
attr_accessor :foo
|
8
|
+
|
9
|
+
def initialize(args)
|
10
|
+
@foo = args[:foo]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
puts "Initialization benchmark\n\n"
|
15
|
+
|
16
|
+
Benchmark.ips do |x|
|
17
|
+
input_hash = { foo: :bar }
|
18
|
+
x.report('OpenStruct') do
|
19
|
+
OpenStruct.new(input_hash)
|
20
|
+
end
|
21
|
+
|
22
|
+
x.report('PersistentOpenStruct') do
|
23
|
+
PersistentOpenStruct.new(input_hash)
|
24
|
+
end
|
25
|
+
|
26
|
+
x.report('OpenFastStruct') do
|
27
|
+
OpenFastStruct.new(input_hash)
|
28
|
+
end
|
29
|
+
|
30
|
+
x.report('RegularClass') do
|
31
|
+
RegularClass.new(input_hash)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
puts "\n\nAssignment Benchmark\n\n"
|
36
|
+
|
37
|
+
Benchmark.ips do |x|
|
38
|
+
os = OpenStruct.new(foo: :bar)
|
39
|
+
pos = PersistentOpenStruct.new(foo: :bar)
|
40
|
+
ofs = OpenFastStruct.new(foo: :bar)
|
41
|
+
rgc = RegularClass.new(foo: :bar)
|
42
|
+
|
43
|
+
x.report('OpenStruct') do
|
44
|
+
os.foo = :bar
|
45
|
+
end
|
46
|
+
|
47
|
+
x.report('PersistentOpenStruct') do
|
48
|
+
pos.foo = :bar
|
49
|
+
end
|
50
|
+
|
51
|
+
x.report('OpenFastStruct') do
|
52
|
+
ofs.foo = :bar
|
53
|
+
end
|
54
|
+
|
55
|
+
x.report('RegularClass') do
|
56
|
+
rgc.foo = :bar
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
puts "\n\nAccess Benchmark\n\n"
|
61
|
+
|
62
|
+
Benchmark.ips do |x|
|
63
|
+
os = OpenStruct.new(foo: :bar)
|
64
|
+
pos = PersistentOpenStruct.new(foo: :bar)
|
65
|
+
ofs = OpenFastStruct.new(foo: :bar)
|
66
|
+
rgc = RegularClass.new(foo: :bar)
|
67
|
+
|
68
|
+
x.report('OpenStruct') do
|
69
|
+
os.foo
|
70
|
+
end
|
71
|
+
|
72
|
+
x.report('PersistentOpenStruct') do
|
73
|
+
pos.foo
|
74
|
+
end
|
75
|
+
|
76
|
+
x.report('OpenFastStruct') do
|
77
|
+
ofs.foo
|
78
|
+
end
|
79
|
+
|
80
|
+
x.report('RegularClass') do
|
81
|
+
pos.foo
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
class PersistentOpenStruct < OpenStruct
|
4
|
+
def new_ostruct_member(name)
|
5
|
+
name = name.to_sym
|
6
|
+
unless respond_to?(name)
|
7
|
+
self.class.send(:define_method, name) { @table[name] }
|
8
|
+
self.class.send(:define_method, "#{name}=") { |x| modifiable[name] = x }
|
9
|
+
end
|
10
|
+
name
|
11
|
+
end
|
12
|
+
protected :new_ostruct_member
|
13
|
+
|
14
|
+
def delete_field(name)
|
15
|
+
@table.delete(name)
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'persistent_open_struct/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "persistent_open_struct"
|
8
|
+
spec.version = PersistentOpenStruct::VERSION
|
9
|
+
spec.authors = ["amcaplan"]
|
10
|
+
spec.email = ["ariel.caplan@vitals.com"]
|
11
|
+
spec.summary = %q{A variant of OpenStruct that persists defined methods}
|
12
|
+
spec.description = %q{Unlike OpenStruct, which defines singleton methods on an object, PersistentOpenStruct defines methods on the class. This is useful when storing many hashes with the same keys as OpenStructs.}
|
13
|
+
spec.homepage = "http://github.com/amcaplan/persistent_open_struct"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.required_ruby_version = '>= 2.1.0'
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
23
|
+
spec.add_development_dependency 'rake', '~> 10.4', '>= 10.4.2'
|
24
|
+
spec.add_development_dependency 'minitest', '~> 5.4', '>= 5.4.3'
|
25
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'persistent_open_struct'
|
3
|
+
|
4
|
+
class PersistentOpenStructTest < Minitest::Test
|
5
|
+
def test_initialize
|
6
|
+
h = {name: "John Smith", age: 70, pension: 300}
|
7
|
+
assert_equal h, PersistentOpenStruct.new(h).to_h
|
8
|
+
assert_equal h, PersistentOpenStruct.new(PersistentOpenStruct.new(h)).to_h
|
9
|
+
assert_equal h, PersistentOpenStruct.new(Struct.new(*h.keys).new(*h.values)).to_h
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_equality
|
13
|
+
o1 = PersistentOpenStruct.new
|
14
|
+
o2 = PersistentOpenStruct.new
|
15
|
+
assert_equal(o1, o2)
|
16
|
+
|
17
|
+
o1.a = 'a'
|
18
|
+
refute_equal(o1, o2)
|
19
|
+
|
20
|
+
o2.a = 'a'
|
21
|
+
assert_equal(o1, o2)
|
22
|
+
|
23
|
+
o1.a = 'b'
|
24
|
+
refute_equal(o1, o2)
|
25
|
+
|
26
|
+
o2 = Object.new
|
27
|
+
o2.instance_eval{@table = {:a => 'b'}}
|
28
|
+
refute_equal(o1, o2)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_inspect
|
32
|
+
foo = PersistentOpenStruct.new
|
33
|
+
assert_equal("#<PersistentOpenStruct>", foo.inspect)
|
34
|
+
foo.bar = 1
|
35
|
+
foo.baz = 2
|
36
|
+
assert_equal("#<PersistentOpenStruct bar=1, baz=2>", foo.inspect)
|
37
|
+
|
38
|
+
foo = PersistentOpenStruct.new
|
39
|
+
foo.bar = PersistentOpenStruct.new
|
40
|
+
assert_equal('#<PersistentOpenStruct bar=#<PersistentOpenStruct>>', foo.inspect)
|
41
|
+
foo.bar.foo = foo
|
42
|
+
assert_equal('#<PersistentOpenStruct bar=#<PersistentOpenStruct foo=#<PersistentOpenStruct ...>>>', foo.inspect)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_frozen
|
46
|
+
o = PersistentOpenStruct.new
|
47
|
+
o.a = 'a'
|
48
|
+
o.freeze
|
49
|
+
assert_raises(RuntimeError) {o.b = 'b'}
|
50
|
+
refute_respond_to(o, :b)
|
51
|
+
assert_raises(RuntimeError) {o.a = 'z'}
|
52
|
+
assert_equal('a', o.a)
|
53
|
+
o = PersistentOpenStruct.new :a => 42
|
54
|
+
def o.frozen?; nil end
|
55
|
+
o.freeze
|
56
|
+
assert_raises(RuntimeError, '[ruby-core:22559]') {o.a = 1764}
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_delete_field
|
60
|
+
o = PersistentOpenStruct.new
|
61
|
+
refute_respond_to(o, :foobar)
|
62
|
+
refute_respond_to(o, :foobar=)
|
63
|
+
o.foobar = :baz
|
64
|
+
assert_equal(o.foobar, :baz)
|
65
|
+
assert_respond_to(o, :foobar)
|
66
|
+
assert_respond_to(o, :foobar=)
|
67
|
+
o.delete_field(:foobar)
|
68
|
+
assert_equal(nil, o.foobar)
|
69
|
+
assert_respond_to(o, :foobar)
|
70
|
+
assert_respond_to(o, :foobar=)
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_setter
|
74
|
+
os = PersistentOpenStruct.new
|
75
|
+
os[:foo] = :bar
|
76
|
+
assert_equal :bar, os.foo
|
77
|
+
os['foo'] = :baz
|
78
|
+
assert_equal :baz, os.foo
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_getter
|
82
|
+
os = PersistentOpenStruct.new
|
83
|
+
os.foo = :bar
|
84
|
+
assert_equal :bar, os[:foo]
|
85
|
+
assert_equal :bar, os['foo']
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_to_h
|
89
|
+
h = {name: "John Smith", age: 70, pension: 300}
|
90
|
+
os = PersistentOpenStruct.new(h)
|
91
|
+
to_h = os.to_h
|
92
|
+
assert_equal(h, to_h)
|
93
|
+
|
94
|
+
to_h[:age] = 71
|
95
|
+
assert_equal(70, os.age)
|
96
|
+
assert_equal(70, h[:age])
|
97
|
+
|
98
|
+
assert_equal(h, PersistentOpenStruct.new("name" => "John Smith", "age" => 70, pension: 300).to_h)
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_each_pair
|
102
|
+
h = {name: "John Smith", age: 70, pension: 300}
|
103
|
+
os = PersistentOpenStruct.new(h)
|
104
|
+
assert_equal '#<Enumerator: #<PersistentOpenStruct name="John Smith", age=70, pension=300>:each_pair>', os.each_pair.inspect
|
105
|
+
assert_equal [[:name, "John Smith"], [:age, 70], [:pension, 300]], os.each_pair.to_a
|
106
|
+
assert_equal 3, os.each_pair.size
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_eql_and_hash
|
110
|
+
os1 = PersistentOpenStruct.new age: 70
|
111
|
+
os2 = PersistentOpenStruct.new age: 70.0
|
112
|
+
assert_equal os1, os2
|
113
|
+
assert_equal false, os1.eql?(os2)
|
114
|
+
refute_equal os1.hash, os2.hash
|
115
|
+
assert_equal true, os1.eql?(os1.dup)
|
116
|
+
assert_equal os1.hash, os1.dup.hash
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_method_missing
|
120
|
+
os = PersistentOpenStruct.new
|
121
|
+
e = assert_raises(NoMethodError) { os.foobarbaz true }
|
122
|
+
assert_equal :foobarbaz, e.name
|
123
|
+
assert_equal [true], e.args
|
124
|
+
assert_match(/#{__callee__}/, e.backtrace[0])
|
125
|
+
e = assert_raises(ArgumentError) { os.send :foobarbaz=, true, true }
|
126
|
+
assert_match(/#{__callee__}/, e.backtrace[0])
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_method_reuse
|
130
|
+
os = PersistentOpenStruct.new
|
131
|
+
refute_respond_to(os, :hello)
|
132
|
+
refute_respond_to(os, :hello=)
|
133
|
+
os.hello = 'world'
|
134
|
+
os2 = PersistentOpenStruct.new
|
135
|
+
assert_respond_to(os2, :hello)
|
136
|
+
assert_respond_to(os2, :hello=)
|
137
|
+
end
|
138
|
+
|
139
|
+
PersistentOpenStructClass1 = Class.new(PersistentOpenStruct)
|
140
|
+
PersistentOpenStructClass2 = Class.new(PersistentOpenStruct)
|
141
|
+
|
142
|
+
def test_method_segregation
|
143
|
+
os1a = PersistentOpenStructClass1.new
|
144
|
+
os1a.a_thing = 'value'
|
145
|
+
os1b = PersistentOpenStructClass1.new
|
146
|
+
assert_respond_to(os1b, :a_thing)
|
147
|
+
os2 = PersistentOpenStructClass2.new
|
148
|
+
refute_respond_to(os2, :a_thing)
|
149
|
+
end
|
150
|
+
end
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: persistent_open_struct
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- amcaplan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-05-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.4'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 10.4.2
|
37
|
+
type: :development
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - "~>"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '10.4'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 10.4.2
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: minitest
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '5.4'
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 5.4.3
|
57
|
+
type: :development
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - "~>"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '5.4'
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 5.4.3
|
67
|
+
description: Unlike OpenStruct, which defines singleton methods on an object, PersistentOpenStruct
|
68
|
+
defines methods on the class. This is useful when storing many hashes with the
|
69
|
+
same keys as OpenStructs.
|
70
|
+
email:
|
71
|
+
- ariel.caplan@vitals.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".travis.yml"
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- benchmark/benchmark.rb
|
83
|
+
- lib/persistent_open_struct.rb
|
84
|
+
- lib/persistent_open_struct/version.rb
|
85
|
+
- persistent_open_struct.gemspec
|
86
|
+
- test/test_helper.rb
|
87
|
+
- test/test_persistent_open_struct.rb
|
88
|
+
homepage: http://github.com/amcaplan/persistent_open_struct
|
89
|
+
licenses:
|
90
|
+
- MIT
|
91
|
+
metadata: {}
|
92
|
+
post_install_message:
|
93
|
+
rdoc_options: []
|
94
|
+
require_paths:
|
95
|
+
- lib
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: 2.1.0
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
requirements: []
|
107
|
+
rubyforge_project:
|
108
|
+
rubygems_version: 2.4.5
|
109
|
+
signing_key:
|
110
|
+
specification_version: 4
|
111
|
+
summary: A variant of OpenStruct that persists defined methods
|
112
|
+
test_files:
|
113
|
+
- test/test_helper.rb
|
114
|
+
- test/test_persistent_open_struct.rb
|