inheritable_instance 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +80 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/inheritable_instance.gemspec +25 -0
- data/lib/inheritable_instance.rb +29 -0
- data/lib/inheritable_instance/includible.rb +9 -0
- data/lib/inheritable_instance/safe_deep_dup.rb +43 -0
- data/lib/inheritable_instance/version.rb +3 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e6838791e50f9ff4c630c2ae217b5200d741df97
|
4
|
+
data.tar.gz: 4cfe14e619e66c20501435aa1a9f50c847a32c2e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 53bb54775f60122eef596cc6279a22dbcbb8741cd63a0589401e3a88218d9a15722228c432bf4676c76fdee67a1f8a1e3817f0a324b4fdebe0a857e8a3f0af55
|
7
|
+
data.tar.gz: 1538da874d1e9f31efee1d62ea1e7aae739e36bd8e936bc293ba0019965fe5409f00f87c6bd107e41a9e550c6ab34193dbd4f4ce139d8d0bc7abd3cfb11d9fd0
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 David Feldman
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
# InheritableInstance
|
2
|
+
|
3
|
+
Allow descending classes to inherit instance variables.
|
4
|
+
This is useful for persisting class-level configuration.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
```ruby
|
10
|
+
gem 'inheritable_instance'
|
11
|
+
```
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
Insert the `InheritableInstance` module into the ancestry chain of your class:
|
16
|
+
```ruby
|
17
|
+
class FakeClass
|
18
|
+
extend InheritableInstance
|
19
|
+
end
|
20
|
+
```
|
21
|
+
|
22
|
+
Then use `inheritable_instance` to set any instance variables
|
23
|
+
that you want to be inherited by subclasses:
|
24
|
+
```ruby
|
25
|
+
class FakeClass
|
26
|
+
inheritable_instance :@thing_one, 1
|
27
|
+
inheritable_instance :@thing_two, 2
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
These variables will be automatically set on inheritance:
|
32
|
+
```ruby
|
33
|
+
class DoubleFake < FakeClass; end
|
34
|
+
DoubleFake.instance_variable_get(:@thing_one) == 1
|
35
|
+
DoubleFake.instance_variable_get(:@thing_two) == 2
|
36
|
+
```
|
37
|
+
|
38
|
+
It is convenient to pair this with the attr_* methods:
|
39
|
+
```ruby
|
40
|
+
class << FakeClass
|
41
|
+
attr_accessor :thing_two
|
42
|
+
end
|
43
|
+
DoubleFake.thing_two = "two"
|
44
|
+
FakeClass.thing_two == 2
|
45
|
+
DoubleFake.thing_two == "two"
|
46
|
+
```
|
47
|
+
|
48
|
+
Note that the values are duplicated (when possible):
|
49
|
+
```ruby
|
50
|
+
class OneTwoThree
|
51
|
+
extend InheritableInstance
|
52
|
+
inheritable_instance :@list, []
|
53
|
+
class << self; attr_reader :list; end
|
54
|
+
end
|
55
|
+
OneTwoThree.list << 1 << 2 << 3
|
56
|
+
Abc = Class.new(OneTwoThree)
|
57
|
+
Abc.list << 'a' << 'b' << 'c'
|
58
|
+
Abc.list == [1,2,3,'a','b','c']
|
59
|
+
OneTwoThree.list == [1,2,3]
|
60
|
+
```
|
61
|
+
|
62
|
+
## Additional Details
|
63
|
+
|
64
|
+
If for some reason it is inconvenient to `extend` the module,
|
65
|
+
there is an `Includible` helper that you can use instead:
|
66
|
+
```ruby
|
67
|
+
class SameAsFakeClass
|
68
|
+
include InheritableInstance::Includible
|
69
|
+
end
|
70
|
+
```
|
71
|
+
|
72
|
+
## Contributing
|
73
|
+
|
74
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/fledman/inheritable_instance.
|
75
|
+
|
76
|
+
|
77
|
+
## License
|
78
|
+
|
79
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
80
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "inheritable_instance"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -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 'inheritable_instance/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "inheritable_instance"
|
8
|
+
spec.version = InheritableInstance::VERSION
|
9
|
+
spec.authors = ["David Feldman"]
|
10
|
+
spec.email = ["dbfeldman@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = "Allow descendants to inherit instance variables"
|
13
|
+
spec.description = "Useful for persisting class-level configuration to subclasses"
|
14
|
+
spec.homepage = "https://github.com/fledman/inheritable_instance"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.11"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.4"
|
24
|
+
spec.add_development_dependency "pry", "~>0.10"
|
25
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "inheritable_instance/version"
|
2
|
+
require "inheritable_instance/safe_deep_dup"
|
3
|
+
require "inheritable_instance/includible"
|
4
|
+
require "set"
|
5
|
+
|
6
|
+
module InheritableInstance
|
7
|
+
|
8
|
+
def inheritable_instance(ivar, value)
|
9
|
+
ivar = ivar.to_sym
|
10
|
+
inheritable_instance_vars << ivar
|
11
|
+
instance_variable_set ivar, value
|
12
|
+
end
|
13
|
+
|
14
|
+
def inherited(subclass)
|
15
|
+
super
|
16
|
+
inheritable_instance_vars.each do |ivar|
|
17
|
+
original = instance_variable_get(ivar)
|
18
|
+
duplicate = SafeDeepDup.duplicate(original)
|
19
|
+
subclass.instance_variable_set(ivar, duplicate)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def inheritable_instance_vars
|
26
|
+
@inheritable_instance_vars ||= Set.new([:@inheritable_instance_vars])
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "bigdecimal"
|
2
|
+
|
3
|
+
module InheritableInstance
|
4
|
+
module SafeDeepDup
|
5
|
+
extend self
|
6
|
+
|
7
|
+
SKIP = [ NilClass, FalseClass, TrueClass,
|
8
|
+
Symbol, Module, Method, UnboundMethod ].freeze
|
9
|
+
|
10
|
+
def duplicate(obj)
|
11
|
+
return duplicate_hash(obj) if obj.is_a?(Hash)
|
12
|
+
return duplicate_array(obj) if obj.is_a?(Array)
|
13
|
+
return obj.dup if should_duplicate?(obj)
|
14
|
+
obj
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def should_duplicate?(obj)
|
20
|
+
return false if SKIP.any?{ |klass| obj.is_a?(klass) }
|
21
|
+
return false if obj.is_a?(Numeric) && !obj.is_a?(BigDecimal)
|
22
|
+
return false unless obj.respond_to?(:dup)
|
23
|
+
!obj.respond_to?(:duplicable?) || obj.duplicable?
|
24
|
+
end
|
25
|
+
|
26
|
+
def duplicate_array(array)
|
27
|
+
array.map{ |element| duplicate(element) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def duplicate_hash(hash)
|
31
|
+
hash.each_with_object(blank_hash(hash)) do |(k, v), copy|
|
32
|
+
copy[duplicate(k)] = duplicate(v)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def blank_hash(hash)
|
37
|
+
return hash.dup.clear unless hash.class.equal?(Hash)
|
38
|
+
hash.default_proc ? Hash.new(&hash.default_proc) :
|
39
|
+
Hash.new(hash.default)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: inheritable_instance
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- David Feldman
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-05-31 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.11'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.11'
|
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.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.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: '3.4'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.4'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.10'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.10'
|
69
|
+
description: Useful for persisting class-level configuration to subclasses
|
70
|
+
email:
|
71
|
+
- dbfeldman@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rspec"
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- bin/console
|
83
|
+
- bin/setup
|
84
|
+
- inheritable_instance.gemspec
|
85
|
+
- lib/inheritable_instance.rb
|
86
|
+
- lib/inheritable_instance/includible.rb
|
87
|
+
- lib/inheritable_instance/safe_deep_dup.rb
|
88
|
+
- lib/inheritable_instance/version.rb
|
89
|
+
homepage: https://github.com/fledman/inheritable_instance
|
90
|
+
licenses:
|
91
|
+
- MIT
|
92
|
+
metadata: {}
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
requirements: []
|
108
|
+
rubyforge_project:
|
109
|
+
rubygems_version: 2.4.5.1
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: Allow descendants to inherit instance variables
|
113
|
+
test_files: []
|