finer_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 +17 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +72 -0
- data/Rakefile +1 -0
- data/finer_struct.gemspec +24 -0
- data/lib/finer_struct/immutable.rb +38 -0
- data/lib/finer_struct/mutable.rb +47 -0
- data/lib/finer_struct/version.rb +3 -0
- data/lib/finer_struct.rb +4 -0
- data/spec/finer_struct/immutable_spec.rb +28 -0
- data/spec/finer_struct/mutable_spec.rb +29 -0
- data/spec/finer_struct/shared_examples.rb +12 -0
- metadata +102 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 6ff4c771933bc1229752c3dd6fbfb219d5b55604
|
|
4
|
+
data.tar.gz: 0b77229e6afe0798f66c7dd0c59c6c2988f01d6a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 17822ca2377411bbf76ff5f81815b75a3639f5b09d4fc2e23488efc6ddd1ed53d94c2871ca541f02261dc3aec9bb8ad9e7d317277ecd448bc1b6c0d74e73d730
|
|
7
|
+
data.tar.gz: ed4d9c72e5898f3a2c8c5e398498ba717b61703c0d17e336991be1455f301781ab17e514d4621ff5d08e360e8b16e069ffdf12aa06db4aacb535e6955985fdee
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2013 Pete Yandell
|
|
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,72 @@
|
|
|
1
|
+
# FinerStruct
|
|
2
|
+
|
|
3
|
+
A nicer replacement for Ruby's Struct and OpenStruct.
|
|
4
|
+
|
|
5
|
+
Isn't it annoying how `OpenStruct.new` takes a hash, but the the arguments to `Struct.new` have to be ordered?
|
|
6
|
+
|
|
7
|
+
Do you find you always use an `OpenStruct` when you don't really care if it's open, you just want an easy way to create an object from a hash?
|
|
8
|
+
|
|
9
|
+
Did you know that creating an `OpenStruct` blows away Ruby's method cache?
|
|
10
|
+
|
|
11
|
+
Isn't it irritating how you have to remember that, to use `OpenStruct`, you need to `require 'ostruct'`?
|
|
12
|
+
|
|
13
|
+
Have you ever wished you could create a `Struct` or `OpenStruct`, but make it immutable?
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
Add this line to your application's Gemfile:
|
|
18
|
+
|
|
19
|
+
gem 'finer_struct'
|
|
20
|
+
|
|
21
|
+
And then execute:
|
|
22
|
+
|
|
23
|
+
$ bundle
|
|
24
|
+
|
|
25
|
+
Or install it yourself as:
|
|
26
|
+
|
|
27
|
+
$ gem install finer_struct
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
### Immutable Structs
|
|
32
|
+
|
|
33
|
+
Immutable structs can't have their attributes changed after creation.
|
|
34
|
+
|
|
35
|
+
#### Anonymous immutable structs
|
|
36
|
+
|
|
37
|
+
struct = FinerStruct::Immutable.new(a: 1, b: 2)
|
|
38
|
+
|
|
39
|
+
struct.a # => 1
|
|
40
|
+
struct.b # => 2
|
|
41
|
+
struct.a = 3 # Exception!
|
|
42
|
+
|
|
43
|
+
#### Named immutable structs
|
|
44
|
+
|
|
45
|
+
class MyStruct < FinerStruct::Immutable(:a, :b)
|
|
46
|
+
struct = MyStruct.new(a: 1, b: 2)
|
|
47
|
+
|
|
48
|
+
MyStruct.new(a: 1, b: 2, c: 3) # Exception!
|
|
49
|
+
|
|
50
|
+
### Mutable Structs
|
|
51
|
+
|
|
52
|
+
Mutable structs let you assign attributes at any time.
|
|
53
|
+
|
|
54
|
+
#### Anonymous mutable structs
|
|
55
|
+
|
|
56
|
+
struct = FinerStruct::Mutable.new(a: 1, b: 2)
|
|
57
|
+
|
|
58
|
+
struct.a = 3
|
|
59
|
+
struct.a # => 3
|
|
60
|
+
|
|
61
|
+
#### Named mutable structs
|
|
62
|
+
|
|
63
|
+
class MyStruct < FinerStruct::Mutable(:a, :b)
|
|
64
|
+
struct = MyStruct.new(a: 1, b: 2)
|
|
65
|
+
|
|
66
|
+
## Contributing
|
|
67
|
+
|
|
68
|
+
1. Fork it
|
|
69
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
70
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
71
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
72
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'finer_struct/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "finer_struct"
|
|
8
|
+
spec.version = FinerStruct::VERSION
|
|
9
|
+
spec.authors = ["Pete Yandell"]
|
|
10
|
+
spec.email = ["pete@notahat.com"]
|
|
11
|
+
spec.description = %q{Nicer replacement for Ruby's Struct and OpenStruct}
|
|
12
|
+
spec.summary = %q{Nicer replacement for Ruby's Struct and OpenStruct}
|
|
13
|
+
spec.homepage = ""
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files`.split($/)
|
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
18
|
+
spec.test_files = spec.files.grep(%r{^(spec)/})
|
|
19
|
+
spec.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
|
22
|
+
spec.add_development_dependency "rake"
|
|
23
|
+
spec.add_development_dependency "rspec"
|
|
24
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module FinerStruct
|
|
2
|
+
|
|
3
|
+
class Immutable
|
|
4
|
+
def initialize(attributes = {})
|
|
5
|
+
@attributes = attributes.dup
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def method_missing(method, *arguments)
|
|
9
|
+
if @attributes.has_key?(method)
|
|
10
|
+
@attributes[method]
|
|
11
|
+
else
|
|
12
|
+
super
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.Immutable(*attribute_names)
|
|
18
|
+
Class.new do
|
|
19
|
+
@attribute_names = attribute_names
|
|
20
|
+
|
|
21
|
+
class << self
|
|
22
|
+
attr_reader :attribute_names
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
attr_reader(*attribute_names)
|
|
26
|
+
|
|
27
|
+
def initialize(attributes = {})
|
|
28
|
+
attributes.each_pair do |key, value|
|
|
29
|
+
unless self.class.attribute_names.include?(key)
|
|
30
|
+
raise(ArgumentError, "no such attribute: #{key}")
|
|
31
|
+
end
|
|
32
|
+
instance_variable_set("@#{key}", value)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'finer_struct/immutable'
|
|
2
|
+
|
|
3
|
+
module FinerStruct
|
|
4
|
+
|
|
5
|
+
class Mutable < Immutable
|
|
6
|
+
def method_missing(method, *arguments)
|
|
7
|
+
if is_assigment?(method) && @attributes.has_key?(key_for_assignment(method))
|
|
8
|
+
@attributes[key_for_assignment(method)] = arguments[0]
|
|
9
|
+
else
|
|
10
|
+
super
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def is_assigment?(method)
|
|
17
|
+
method.to_s.end_with?("=")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def key_for_assignment(method)
|
|
21
|
+
method.to_s[0..-2].to_sym
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.Mutable(*attribute_names)
|
|
26
|
+
Class.new do
|
|
27
|
+
@attribute_names = attribute_names
|
|
28
|
+
|
|
29
|
+
class << self
|
|
30
|
+
attr_reader :attribute_names
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
attr_accessor(*attribute_names)
|
|
34
|
+
|
|
35
|
+
def initialize(attributes = {})
|
|
36
|
+
attributes.each_pair do |key, value|
|
|
37
|
+
unless self.class.attribute_names.include?(key)
|
|
38
|
+
raise(ArgumentError, "no such attribute: #{key}")
|
|
39
|
+
end
|
|
40
|
+
instance_variable_set("@#{key}", value)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
|
data/lib/finer_struct.rb
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'finer_struct/immutable'
|
|
2
|
+
require 'finer_struct/shared_examples'
|
|
3
|
+
|
|
4
|
+
shared_examples "an immutable struct" do
|
|
5
|
+
it_behaves_like "a struct"
|
|
6
|
+
|
|
7
|
+
it "complains if you try to write an attribute" do
|
|
8
|
+
expect { subject.a = 3 }.to raise_error(NoMethodError)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module FinerStruct
|
|
13
|
+
|
|
14
|
+
describe "an anonymous immutable struct" do
|
|
15
|
+
subject { FinerStruct::Immutable.new(a: 1, b: 2) }
|
|
16
|
+
|
|
17
|
+
it_behaves_like "an immutable struct"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe "a named immutable struct" do
|
|
21
|
+
let(:klass) { FinerStruct::Immutable(:a, :b) }
|
|
22
|
+
subject { klass.new(a: 1, b: 2) }
|
|
23
|
+
|
|
24
|
+
it_behaves_like "an immutable struct"
|
|
25
|
+
it_behaves_like "a named struct"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'finer_struct/mutable'
|
|
2
|
+
require 'finer_struct/shared_examples'
|
|
3
|
+
|
|
4
|
+
shared_examples "a mutable struct" do
|
|
5
|
+
it_behaves_like "a struct"
|
|
6
|
+
|
|
7
|
+
it "lets you write attributes" do
|
|
8
|
+
subject.a = 3
|
|
9
|
+
expect(subject.a).to eq(3)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
module FinerStruct
|
|
14
|
+
|
|
15
|
+
describe "an anonymous mutable struct" do
|
|
16
|
+
subject { FinerStruct::Mutable.new(a: 1, b: 2) }
|
|
17
|
+
|
|
18
|
+
it_behaves_like "a mutable struct"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe "a named mutable struct" do
|
|
22
|
+
let(:klass) { FinerStruct::Mutable(:a, :b) }
|
|
23
|
+
subject { klass.new(a: 1, b: 2) }
|
|
24
|
+
|
|
25
|
+
it_behaves_like "a mutable struct"
|
|
26
|
+
it_behaves_like "a named struct"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
shared_examples "a struct" do
|
|
2
|
+
it "lets you read attributes" do
|
|
3
|
+
expect(subject.a).to eq(1)
|
|
4
|
+
expect(subject.b).to eq(2)
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
shared_examples "a named struct" do
|
|
9
|
+
it "complains if you set an attribute that the struct doesn't have" do
|
|
10
|
+
expect { klass.new(c: 3) }.to raise_error(ArgumentError, "no such attribute: c")
|
|
11
|
+
end
|
|
12
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: finer_struct
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Pete Yandell
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2013-06-24 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.3'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ~>
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.3'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rake
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - '>='
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - '>='
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - '>='
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - '>='
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
description: Nicer replacement for Ruby's Struct and OpenStruct
|
|
56
|
+
email:
|
|
57
|
+
- pete@notahat.com
|
|
58
|
+
executables: []
|
|
59
|
+
extensions: []
|
|
60
|
+
extra_rdoc_files: []
|
|
61
|
+
files:
|
|
62
|
+
- .gitignore
|
|
63
|
+
- Gemfile
|
|
64
|
+
- LICENSE.txt
|
|
65
|
+
- README.md
|
|
66
|
+
- Rakefile
|
|
67
|
+
- finer_struct.gemspec
|
|
68
|
+
- lib/finer_struct.rb
|
|
69
|
+
- lib/finer_struct/immutable.rb
|
|
70
|
+
- lib/finer_struct/mutable.rb
|
|
71
|
+
- lib/finer_struct/version.rb
|
|
72
|
+
- spec/finer_struct/immutable_spec.rb
|
|
73
|
+
- spec/finer_struct/mutable_spec.rb
|
|
74
|
+
- spec/finer_struct/shared_examples.rb
|
|
75
|
+
homepage: ''
|
|
76
|
+
licenses:
|
|
77
|
+
- MIT
|
|
78
|
+
metadata: {}
|
|
79
|
+
post_install_message:
|
|
80
|
+
rdoc_options: []
|
|
81
|
+
require_paths:
|
|
82
|
+
- lib
|
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
|
+
requirements:
|
|
85
|
+
- - '>='
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: '0'
|
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
|
+
requirements:
|
|
90
|
+
- - '>='
|
|
91
|
+
- !ruby/object:Gem::Version
|
|
92
|
+
version: '0'
|
|
93
|
+
requirements: []
|
|
94
|
+
rubyforge_project:
|
|
95
|
+
rubygems_version: 2.0.3
|
|
96
|
+
signing_key:
|
|
97
|
+
specification_version: 4
|
|
98
|
+
summary: Nicer replacement for Ruby's Struct and OpenStruct
|
|
99
|
+
test_files:
|
|
100
|
+
- spec/finer_struct/immutable_spec.rb
|
|
101
|
+
- spec/finer_struct/mutable_spec.rb
|
|
102
|
+
- spec/finer_struct/shared_examples.rb
|