value_struct 0.5.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.
- data/.document +3 -0
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +4 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +20 -0
- data/README.md +68 -0
- data/Rakefile +34 -0
- data/gemspec.yml +18 -0
- data/lib/value_struct.rb +27 -0
- data/lib/value_struct/core.rb +12 -0
- data/lib/value_struct/dup_with_changes.rb +20 -0
- data/lib/value_struct/freeze.rb +6 -0
- data/lib/value_struct/strict_arguments.rb +8 -0
- data/lib/value_struct/to_h.rb +5 -0
- data/lib/value_struct/version.rb +3 -0
- data/spec/benchmark.rb +44 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/struct_value_spec.rb +94 -0
- data/value_struct.gemspec +60 -0
- metadata +229 -0
data/.document
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour --format documentation
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown --title "read_only Documentation" --protected
|
data/ChangeLog.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Jan Lelis
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# Value Struct
|
2
|
+
|
3
|
+
A value struct is a subclass of normal [Ruby struct](http://blog.grayproductions.net/articles/all_about_struct) that behaves almost the same. However, it has a major difference:
|
4
|
+
|
5
|
+
__Value structs are immutable, i.e. they don't have setters (although, not recursively*)__
|
6
|
+
|
7
|
+
This gem also provides the following (optional) mixins, to make life easier when using immutable structs:
|
8
|
+
|
9
|
+
* __DupWithChanges__ #dup takes a optional hash for setting new values
|
10
|
+
* __StrictArguments__ Value structs need to be initialized with the exact amount of arguments
|
11
|
+
* __Freeze__ Automatically freeze new instances
|
12
|
+
* __ToH__ #to_h for converting into a hash (if Ruby version below < 2.0)
|
13
|
+
|
14
|
+
By default, only the DupWithChanges and ToH mixins get included.
|
15
|
+
|
16
|
+
## Why?
|
17
|
+
|
18
|
+
Sometimes you want to eliminate state. See [this blog article] for more information.
|
19
|
+
|
20
|
+
## Performance
|
21
|
+
|
22
|
+
Without mixins, ValueStructs are as fast as normal structs. Some (optional) mixins add noticable overhead, e.g. StrictArguments
|
23
|
+
|
24
|
+
## How to use structs with mixins
|
25
|
+
|
26
|
+
Point = ValueStruct.new_with_mixins :x, :y, [
|
27
|
+
ValueStruct::DupWithChanges,
|
28
|
+
ValueStruct::ToH,
|
29
|
+
ValueStruct::StrictArguments,
|
30
|
+
ValueStruct::Freeze,
|
31
|
+
]
|
32
|
+
|
33
|
+
## Example
|
34
|
+
|
35
|
+
require 'value_struct'
|
36
|
+
|
37
|
+
Point = ValueStruct.new(:x, :y) do # methods defined in the block will be available in your new value struct class
|
38
|
+
# ...
|
39
|
+
end
|
40
|
+
|
41
|
+
Please refer to the [documentation of Ruby's struct] for more details on usage.
|
42
|
+
|
43
|
+
## *
|
44
|
+
|
45
|
+
Because of the nature of Ruby, most things are not really immutable. So if you have an attribute `:by` and initialize it with an array, you cannot change the value struct anymore, but still the array:
|
46
|
+
|
47
|
+
Ru = ValueStruct.new(:by)
|
48
|
+
ruby = Ru.by([1,2,3])
|
49
|
+
ruby.by # => [1,2,3]
|
50
|
+
|
51
|
+
ruby.by = [1,2,3,4] # not possible
|
52
|
+
ruby.by << 4 # possible
|
53
|
+
|
54
|
+
## Install
|
55
|
+
|
56
|
+
$ gem install value_struct
|
57
|
+
|
58
|
+
## Todo
|
59
|
+
|
60
|
+
* Make test suite clean and useful
|
61
|
+
|
62
|
+
## Influenced by / Thanks to
|
63
|
+
|
64
|
+
* Ruby Rogues #123
|
65
|
+
* Tom Crayford: [Values](https://github.com/tcrayford/Values)
|
66
|
+
* https://github.com/iconara/immutable_struct
|
67
|
+
|
68
|
+
## J-_-L
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'bundler'
|
7
|
+
rescue LoadError => e
|
8
|
+
warn e.message
|
9
|
+
warn "Run `gem install bundler` to install Bundler."
|
10
|
+
exit -1
|
11
|
+
end
|
12
|
+
|
13
|
+
begin
|
14
|
+
Bundler.setup(:development)
|
15
|
+
rescue Bundler::BundlerError => e
|
16
|
+
warn e.message
|
17
|
+
warn "Run `bundle install` to install missing gems."
|
18
|
+
exit e.status_code
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake'
|
22
|
+
|
23
|
+
require 'rubygems/tasks'
|
24
|
+
Gem::Tasks.new
|
25
|
+
|
26
|
+
require 'rspec/core/rake_task'
|
27
|
+
RSpec::Core::RakeTask.new
|
28
|
+
|
29
|
+
task :test => :spec
|
30
|
+
task :default => :spec
|
31
|
+
|
32
|
+
require 'yard'
|
33
|
+
YARD::Rake::YardocTask.new
|
34
|
+
task :doc => :yard
|
data/gemspec.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
name: value_struct
|
2
|
+
summary: "Struct-like value objects"
|
3
|
+
license: MIT
|
4
|
+
authors: Jan Lelis
|
5
|
+
email: mail@janlelis.de
|
6
|
+
homepage: https://github.com/janlelis/value_struct
|
7
|
+
|
8
|
+
development_dependencies:
|
9
|
+
bundler: ~> 1.0
|
10
|
+
rake: ~> 0.8
|
11
|
+
rspec: ~> 2.4
|
12
|
+
rubygems-tasks: ~> 0.2
|
13
|
+
yard: ~> 0.8
|
14
|
+
kramdown: ~> 0.14
|
15
|
+
debugger: ~> 1.2.1
|
16
|
+
values: ~> 1.2.1
|
17
|
+
immutable_struct: ~> 1.0.2
|
18
|
+
hamster: ~> 0.4.3
|
data/lib/value_struct.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative 'value_struct/version'
|
2
|
+
require_relative 'value_struct/core'
|
3
|
+
require_relative 'value_struct/to_h'
|
4
|
+
require_relative 'value_struct/dup_with_changes'
|
5
|
+
require_relative 'value_struct/strict_arguments'
|
6
|
+
require_relative 'value_struct/freeze'
|
7
|
+
|
8
|
+
class ValueStruct < Struct
|
9
|
+
def self.build(*args, &block)
|
10
|
+
struct_class = Struct.new(*args, &block)
|
11
|
+
struct_class.send(:include, ValueStruct::Core)
|
12
|
+
struct_class
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.new_with_mixins(*args, mixins, &block)
|
16
|
+
raise ArgumentError, 'mixin list (last paramater) must be an array' unless mixins.is_a? Array
|
17
|
+
struct_class = build(*args, &block)
|
18
|
+
mixins.each{ |mixin| struct_class.send(:include, mixin) }
|
19
|
+
struct_class
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.new(*args, &block)
|
23
|
+
mixins = [ValueStruct::DupWithChanges]
|
24
|
+
mixins.unshift(ValueStruct::ToH) if RUBY_VERSION < "2.0"
|
25
|
+
new_with_mixins(*args, mixins, &block)
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module ValueStruct::Core
|
2
|
+
def inspect
|
3
|
+
super.to_s.sub('struct', 'ValueStruct')
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.included(struct)
|
7
|
+
struct.send(:undef_method, "[]=".to_sym)
|
8
|
+
struct.members.each do |member|
|
9
|
+
struct.send(:undef_method, "#{member}=".to_sym)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ValueStruct::DupWithChanges
|
2
|
+
def dup(changes = {})
|
3
|
+
case changes
|
4
|
+
when {}
|
5
|
+
new(values)
|
6
|
+
when Hash
|
7
|
+
new(
|
8
|
+
members.zip(values).map{ |member, value|
|
9
|
+
if changes.has_key?(m)
|
10
|
+
changes[m]
|
11
|
+
else
|
12
|
+
value
|
13
|
+
end
|
14
|
+
}
|
15
|
+
)
|
16
|
+
else
|
17
|
+
raise ArgumentError, 'dup must be given a Hash or nothing'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/spec/benchmark.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require_relative '../lib/value_struct'
|
2
|
+
require 'benchmark'
|
3
|
+
require 'immutable_struct'
|
4
|
+
require 'values'
|
5
|
+
|
6
|
+
COUNT = 200_000
|
7
|
+
|
8
|
+
def benchmark_for(struct_class)
|
9
|
+
puts "%20s: %s" % [
|
10
|
+
struct_class,
|
11
|
+
Benchmark.measure do
|
12
|
+
struct = struct_class.new(:a, :b, :c, :d)
|
13
|
+
COUNT.times{
|
14
|
+
n = struct.new(nil, nil, nil, nil)
|
15
|
+
s = struct.new([1,2,3,4], "value", 23432421412, n)
|
16
|
+
s.a == s.b
|
17
|
+
s.c == s.d
|
18
|
+
s == n
|
19
|
+
}
|
20
|
+
end
|
21
|
+
]
|
22
|
+
end
|
23
|
+
|
24
|
+
def benchmark_for_hash
|
25
|
+
puts "%20s: %s" % [
|
26
|
+
"[Hash]",
|
27
|
+
Benchmark.measure do
|
28
|
+
COUNT.times{
|
29
|
+
n = { a: nil, b: nil, c: nil, d: nil }
|
30
|
+
s = { a: [1,2,3,4], b: "value", c: 23432421412, d: nil }
|
31
|
+
s[:a] == s[:b]
|
32
|
+
s[:c] == s[:d]
|
33
|
+
s == n
|
34
|
+
}
|
35
|
+
end
|
36
|
+
]
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
benchmark_for(Struct)
|
41
|
+
benchmark_for(Value)
|
42
|
+
benchmark_for(ImmutableStruct)
|
43
|
+
benchmark_for(ValueStruct)
|
44
|
+
benchmark_for_hash
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ValueStruct do
|
4
|
+
it "should have a VERSION constant" do
|
5
|
+
ValueStruct.const_get('VERSION').should_not be_empty
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'initialization' do
|
9
|
+
subject do
|
10
|
+
ValueStruct.new(:x, :y)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'creates Class instances' do
|
14
|
+
should be_instance_of Class
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'instance' do
|
19
|
+
subject do
|
20
|
+
Point = ValueStruct.new(:x, :y)
|
21
|
+
Point.new(1,2)
|
22
|
+
end
|
23
|
+
|
24
|
+
it { should be_a Struct }
|
25
|
+
it { should be_a ValueStruct::Core }
|
26
|
+
|
27
|
+
it 'stores values accessible by readers' do
|
28
|
+
subject.x.should == 1
|
29
|
+
subject.y.should == 2
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'does not define setters' do
|
33
|
+
expect{ subject.x = 5 }.to raise_error(NoMethodError)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'does not allow mutatation using []= syntax' do
|
37
|
+
expect{ subject[:x] = 5 }.to raise_error(NoMethodError)
|
38
|
+
end
|
39
|
+
|
40
|
+
# it 'raises argument errors if not given the right number of arguments' do
|
41
|
+
# lambda{
|
42
|
+
# Point.new
|
43
|
+
# }.should raise_error(ArgumentError, 'wrong number of arguments (0 for 2)')
|
44
|
+
# end
|
45
|
+
|
46
|
+
it 'can be inherited from to add methods' do
|
47
|
+
class GraphPoint < ValueStruct.new(:x, :y)
|
48
|
+
def inspect
|
49
|
+
"GraphPoint at #{x},#{y}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
c = GraphPoint.new(0,0)
|
54
|
+
c.inspect.should == 'GraphPoint at 0,0'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#hash and equality' do
|
59
|
+
Y = ValueStruct.new(:x, :y)
|
60
|
+
|
61
|
+
it 'is equal to another value with the same fields' do
|
62
|
+
Point.new(0,0).should == Point.new(0,0)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'is not equal to an object with a different class' do
|
66
|
+
Point.new(0,0).should_not == Y.new(0,0)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'is not equal to another value with different fields' do
|
70
|
+
Point.new(0,0).should_not == Point.new(0,1)
|
71
|
+
Point.new(0,0).should_not == Point.new(1,0)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'has an equal hash if the fields are equal' do
|
75
|
+
p = Point.new(0,0)
|
76
|
+
p.hash.should == Point.new(0,0).hash
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'has a non-equal hash if the fields are different' do
|
80
|
+
p = Point.new(0,0)
|
81
|
+
p.hash.should_not == Point.new(1,0).hash
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'does not have an equal hash if the class is different' do
|
85
|
+
Point.new(0,0).hash.should_not == Y.new(0,0).hash
|
86
|
+
debugger
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# describe '#clone and #dup return the same object' do
|
91
|
+
# it{ subject.object_id.should == subject.clone.object_id }
|
92
|
+
# it{ subject.object_id.should == subject.dup.object_id }
|
93
|
+
# end
|
94
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gemspec = YAML.load_file('gemspec.yml')
|
7
|
+
|
8
|
+
gem.name = gemspec.fetch('name')
|
9
|
+
gem.version = gemspec.fetch('version') do
|
10
|
+
lib_dir = File.join(File.dirname(__FILE__),'lib')
|
11
|
+
$LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
|
12
|
+
|
13
|
+
require 'value_struct'
|
14
|
+
ValueStruct::VERSION
|
15
|
+
end
|
16
|
+
|
17
|
+
gem.summary = gemspec['summary']
|
18
|
+
gem.description = gemspec['description']
|
19
|
+
gem.licenses = Array(gemspec['license'])
|
20
|
+
gem.authors = Array(gemspec['authors'])
|
21
|
+
gem.email = gemspec['email']
|
22
|
+
gem.homepage = gemspec['homepage']
|
23
|
+
|
24
|
+
glob = lambda { |patterns| gem.files & Dir[*patterns] }
|
25
|
+
|
26
|
+
gem.files = `git ls-files`.split($/)
|
27
|
+
gem.files = glob[gemspec['files']] if gemspec['files']
|
28
|
+
|
29
|
+
gem.executables = gemspec.fetch('executables') do
|
30
|
+
glob['bin/*'].map { |path| File.basename(path) }
|
31
|
+
end
|
32
|
+
gem.default_executable = gem.executables.first if Gem::VERSION < '1.7.'
|
33
|
+
|
34
|
+
gem.extensions = glob[gemspec['extensions'] || 'ext/**/extconf.rb']
|
35
|
+
gem.test_files = glob[gemspec['test_files'] || '{test/{**/}*_test.rb']
|
36
|
+
gem.extra_rdoc_files = glob[gemspec['extra_doc_files'] || '*.{txt,md}']
|
37
|
+
|
38
|
+
gem.require_paths = Array(gemspec.fetch('require_paths') {
|
39
|
+
%w[ext lib].select { |dir| File.directory?(dir) }
|
40
|
+
})
|
41
|
+
|
42
|
+
gem.requirements = gemspec['requirements']
|
43
|
+
gem.required_ruby_version = gemspec['required_ruby_version']
|
44
|
+
gem.required_rubygems_version = gemspec['required_rubygems_version']
|
45
|
+
gem.post_install_message = gemspec['post_install_message']
|
46
|
+
|
47
|
+
split = lambda { |string| string.split(/,\s*/) }
|
48
|
+
|
49
|
+
if gemspec['dependencies']
|
50
|
+
gemspec['dependencies'].each do |name,versions|
|
51
|
+
gem.add_dependency(name,split[versions])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
if gemspec['development_dependencies']
|
56
|
+
gemspec['development_dependencies'].each do |name,versions|
|
57
|
+
gem.add_development_dependency(name,split[versions])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
metadata
ADDED
@@ -0,0 +1,229 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: value_struct
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jan Lelis
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0.8'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0.8'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2.4'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.4'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rubygems-tasks
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.2'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0.2'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: yard
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0.8'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0.8'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: kramdown
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0.14'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0.14'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: debugger
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.2.1
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 1.2.1
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: values
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ~>
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: 1.2.1
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ~>
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: 1.2.1
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: immutable_struct
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ~>
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: 1.0.2
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ~>
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: 1.0.2
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: hamster
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ~>
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: 0.4.3
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ~>
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: 0.4.3
|
174
|
+
description: ''
|
175
|
+
email: mail@janlelis.de
|
176
|
+
executables: []
|
177
|
+
extensions: []
|
178
|
+
extra_rdoc_files:
|
179
|
+
- ChangeLog.md
|
180
|
+
- LICENSE.txt
|
181
|
+
- README.md
|
182
|
+
files:
|
183
|
+
- .document
|
184
|
+
- .gitignore
|
185
|
+
- .rspec
|
186
|
+
- .yardopts
|
187
|
+
- ChangeLog.md
|
188
|
+
- Gemfile
|
189
|
+
- LICENSE.txt
|
190
|
+
- README.md
|
191
|
+
- Rakefile
|
192
|
+
- gemspec.yml
|
193
|
+
- lib/value_struct.rb
|
194
|
+
- lib/value_struct/core.rb
|
195
|
+
- lib/value_struct/dup_with_changes.rb
|
196
|
+
- lib/value_struct/freeze.rb
|
197
|
+
- lib/value_struct/strict_arguments.rb
|
198
|
+
- lib/value_struct/to_h.rb
|
199
|
+
- lib/value_struct/version.rb
|
200
|
+
- spec/benchmark.rb
|
201
|
+
- spec/spec_helper.rb
|
202
|
+
- spec/struct_value_spec.rb
|
203
|
+
- value_struct.gemspec
|
204
|
+
homepage: https://github.com/janlelis/value_struct
|
205
|
+
licenses:
|
206
|
+
- MIT
|
207
|
+
post_install_message:
|
208
|
+
rdoc_options: []
|
209
|
+
require_paths:
|
210
|
+
- lib
|
211
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
212
|
+
none: false
|
213
|
+
requirements:
|
214
|
+
- - ! '>='
|
215
|
+
- !ruby/object:Gem::Version
|
216
|
+
version: '0'
|
217
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
218
|
+
none: false
|
219
|
+
requirements:
|
220
|
+
- - ! '>='
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '0'
|
223
|
+
requirements: []
|
224
|
+
rubyforge_project:
|
225
|
+
rubygems_version: 1.8.24
|
226
|
+
signing_key:
|
227
|
+
specification_version: 3
|
228
|
+
summary: Struct-like value objects
|
229
|
+
test_files: []
|