hash_out 0.1.4 → 0.2.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.
- checksums.yaml +4 -4
- data/.travis.yml +0 -1
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/README.md +29 -7
- data/lib/hash_out.rb +19 -0
- data/lib/hash_out/call_registry.rb +6 -9
- data/lib/hash_out/delegator_excludable.rb +11 -0
- data/lib/hash_out/delegator_registry.rb +27 -0
- data/lib/hash_out/excludable.rb +12 -3
- data/lib/hash_out/hasher.rb +10 -11
- data/lib/hash_out/object_wrapper.rb +5 -8
- data/lib/hash_out/object_wrapper/delegated.rb +9 -0
- data/lib/hash_out/version.rb +1 -1
- data/lib/init_attrs.rb +46 -0
- data/lib/last_call.rb +1 -1
- data/spec/features/compatible_with_delegators_spec.rb +59 -0
- metadata +10 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 18c9acb44220caec2192ec5e88db339e3ee2d206
|
4
|
+
data.tar.gz: bd0dda418d17c604f4257f3b15fe8152f0addbee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11961d83bcc9a1441c0e3351e503b53e614fd7c59a150d0a2a3e93638e8bfce6dc7ca6112479e9d847ef2c60e9cd4fba332a63f4b7cb005108399c3b4fe4003a
|
7
|
+
data.tar.gz: 932cb9c2a0c88e881b0b9f528211f6eb49c4b35f01fbf34057c444f1b7a5389d5abe47875c61bb4093fc94517a1503b8925f41c15a27c791611395e08d4ba013
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
### version 0.2.0 - *August 15, 2013*
|
2
|
+
* Makes hash_out compatible with Forwardable
|
3
|
+
* Includes `#excluded_delegators_from_hash_out` class method
|
4
|
+
|
1
5
|
### version 0.1.4 - *July 18, 2013*
|
2
6
|
* Fixes bug (issue #1): `#exclude_from_hash_out` does not block mutation that may happen in the call.
|
3
7
|
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -7,7 +7,7 @@ Include `HashOut` to your class and convert your object to a hash with the `#has
|
|
7
7
|
## Install
|
8
8
|
Add to your Gemfile:
|
9
9
|
```ruby
|
10
|
-
gem 'hash_out', '~> 0.
|
10
|
+
gem 'hash_out', '~> 0.2'
|
11
11
|
```
|
12
12
|
|
13
13
|
Or install it from the command line:
|
@@ -142,6 +142,34 @@ movie.hash_out
|
|
142
142
|
# => {:title=>"Fire Walk With Me", :director=>'David Lynch'}
|
143
143
|
```
|
144
144
|
|
145
|
+
Delegators introduced by Forwardable can be excluded by including
|
146
|
+
`#exclude_delegators_from_hash_out`. (`Forwardable` must be
|
147
|
+
extended *before* `HashOut` is included.)
|
148
|
+
```ruby
|
149
|
+
require 'hash_out'
|
150
|
+
require 'forwardable'
|
151
|
+
|
152
|
+
class Movie
|
153
|
+
extend Forwardable
|
154
|
+
include HashOut
|
155
|
+
|
156
|
+
exclude_delegators_from_hash_out
|
157
|
+
|
158
|
+
def_delegator :@title, :upcase
|
159
|
+
|
160
|
+
def initialize
|
161
|
+
@title = 'Fire Walk With Me'
|
162
|
+
end
|
163
|
+
|
164
|
+
def screaming_title
|
165
|
+
upcase
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
Movie.new.hash_out
|
170
|
+
# => {:screaming_title=>"FIRE WALK WITH ME"}
|
171
|
+
```
|
172
|
+
|
145
173
|
## Contribute
|
146
174
|
1. Fork the repo.
|
147
175
|
2. Create a branch.
|
@@ -149,12 +177,6 @@ movie.hash_out
|
|
149
177
|
4. Ensure the specs are green (`$ rake`)
|
150
178
|
5. Open a pull request.
|
151
179
|
|
152
|
-
## TODO
|
153
|
-
* Bug: make `#hash_out` work with SimpleDelegator
|
154
|
-
* Provide class method that offers custom delegator for `#hash_out`
|
155
|
-
* Provide class method that offers alternative to `exclude_from_hash_out`
|
156
|
-
* Provide class method that allows for inclusion of protected and private methods in resulting hash.
|
157
|
-
|
158
180
|
## License
|
159
181
|
The MIT License (MIT)
|
160
182
|
|
data/lib/hash_out.rb
CHANGED
@@ -1,9 +1,22 @@
|
|
1
1
|
require 'last_call'
|
2
|
+
require 'init_attrs'
|
3
|
+
require 'forwardable'
|
2
4
|
require 'hash_out/hasher'
|
3
5
|
require 'hash_out/call_registry'
|
4
6
|
require 'hash_out/object_wrapper'
|
7
|
+
require 'hash_out/object_wrapper/delegated'
|
8
|
+
require 'hash_out/delegator_registry'
|
5
9
|
|
6
10
|
module HashOut
|
11
|
+
include LastCall
|
12
|
+
|
13
|
+
def self.included base
|
14
|
+
if base.is_a? Forwardable
|
15
|
+
base.extend DelegatorRegistry
|
16
|
+
base.send :include, Delegated
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
7
20
|
def hash_out
|
8
21
|
_register_call last_call
|
9
22
|
_hasher.object_to_hash
|
@@ -28,4 +41,10 @@ module HashOut
|
|
28
41
|
end
|
29
42
|
|
30
43
|
def exclude_from_hash_out; end;
|
44
|
+
|
45
|
+
module Delegated
|
46
|
+
def _wrapped_self
|
47
|
+
@_wrapped_self ||= ObjectWrapper::Delegated.new self
|
48
|
+
end
|
49
|
+
end
|
31
50
|
end
|
@@ -1,24 +1,21 @@
|
|
1
1
|
module HashOut
|
2
|
-
class CallRegistry
|
3
|
-
|
2
|
+
class CallRegistry < Struct.new :hash_out_caller
|
3
|
+
include InitAttrs
|
4
4
|
|
5
|
-
|
6
|
-
@times_called = 0
|
7
|
-
@hash_out_caller = hash_out_caller
|
8
|
-
end
|
5
|
+
init_accessor :times_called, ->{ 0 }
|
9
6
|
|
10
7
|
def register_call
|
11
|
-
|
8
|
+
self.times_called += 1
|
12
9
|
end
|
13
10
|
|
14
11
|
def delete_caller_from hash
|
15
|
-
hash.delete hash_out_caller
|
12
|
+
hash.delete hash_out_caller if internal_call?
|
16
13
|
end
|
17
14
|
|
18
15
|
private
|
19
16
|
|
20
17
|
def internal_call?
|
21
|
-
|
18
|
+
times_called > 1
|
22
19
|
end
|
23
20
|
end
|
24
21
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module HashOut
|
2
|
+
module DelegatorRegistry
|
3
|
+
def exclude_delegators_from_hash_out
|
4
|
+
@register_delegators = true
|
5
|
+
end
|
6
|
+
|
7
|
+
def def_instance_delegator *args
|
8
|
+
register_delegator args[-1] if register_delegators?
|
9
|
+
super
|
10
|
+
end
|
11
|
+
alias def_delegator def_instance_delegator
|
12
|
+
|
13
|
+
def delegators
|
14
|
+
@delegators ||= []
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def register_delegator delegator
|
20
|
+
delegators.push delegator
|
21
|
+
end
|
22
|
+
|
23
|
+
def register_delegators?
|
24
|
+
!!@register_delegators
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/hash_out/excludable.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module HashOut
|
2
2
|
module Excludable
|
3
|
+
include LastCall
|
4
|
+
|
3
5
|
def exclusions
|
4
6
|
@exclusions ||= []
|
5
7
|
end
|
@@ -8,12 +10,19 @@ module HashOut
|
|
8
10
|
exclusions.push last_call
|
9
11
|
end
|
10
12
|
|
11
|
-
def
|
13
|
+
def exclude_exclusions_from methods
|
14
|
+
execute methods
|
15
|
+
delete_exclusions_from methods
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def execute methods
|
12
21
|
methods.each { |method| send method }
|
13
22
|
end
|
14
23
|
|
15
|
-
def
|
16
|
-
|
24
|
+
def delete_exclusions_from methods
|
25
|
+
methods.delete_if { |method| exclusions.include? method }
|
17
26
|
end
|
18
27
|
end
|
19
28
|
end
|
data/lib/hash_out/hasher.rb
CHANGED
@@ -1,32 +1,31 @@
|
|
1
1
|
require 'hash_out/excludable'
|
2
|
-
require 'forwardable'
|
3
2
|
|
4
3
|
module HashOut
|
5
4
|
class Hasher < Struct.new :object, :call_registry
|
6
|
-
extend
|
5
|
+
extend Forwardable
|
6
|
+
include InitAttrs
|
7
7
|
|
8
|
-
def_delegator :object, :excludable, :
|
8
|
+
def_delegator :object, :excludable, :excludable_object
|
9
|
+
init_accessor :hashable_methods do
|
10
|
+
object.public_methods_requiring_no_args
|
11
|
+
end
|
9
12
|
|
10
13
|
def object_to_hash
|
11
14
|
prepare_hashable_methods
|
12
|
-
delete_excluded_methods
|
13
15
|
Hash[hashable_method_value_pairs]
|
14
16
|
end
|
15
17
|
|
16
18
|
private
|
17
19
|
|
18
20
|
def prepare_hashable_methods
|
19
|
-
|
20
|
-
call_registry.delete_caller_from @hashable_methods
|
21
|
-
end
|
21
|
+
methods = hashable_methods
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
excludable_obj.delete_exclusions @hashable_methods
|
23
|
+
call_registry.delete_caller_from methods
|
24
|
+
excludable_object.exclude_exclusions_from methods
|
26
25
|
end
|
27
26
|
|
28
27
|
def hashable_method_value_pairs
|
29
|
-
|
28
|
+
hashable_methods.map do |method|
|
30
29
|
object.method_value_pair method
|
31
30
|
end
|
32
31
|
end
|
@@ -1,15 +1,12 @@
|
|
1
1
|
require 'hash_out/excludable'
|
2
|
-
require 'forwardable'
|
3
2
|
|
4
3
|
module HashOut
|
5
4
|
class ObjectWrapper < Struct.new :object
|
6
|
-
|
5
|
+
include InitAttrs
|
6
|
+
extend Forwardable
|
7
7
|
|
8
8
|
def_delegators :object, :dup, :public_methods, :send, :method
|
9
|
-
|
10
|
-
def excludable
|
11
|
-
@excludable ||= dup.extend Excludable
|
12
|
-
end
|
9
|
+
init_reader :excludable, ->{ dup.extend Excludable }
|
13
10
|
|
14
11
|
def public_methods_requiring_no_args
|
15
12
|
public_methods(false).select { |method| requires_no_args? method }
|
@@ -21,8 +18,8 @@ module HashOut
|
|
21
18
|
|
22
19
|
private
|
23
20
|
|
24
|
-
def requires_no_args?
|
25
|
-
[-1, 0].include? method(
|
21
|
+
def requires_no_args? method
|
22
|
+
[-1, 0].include? method(method).arity
|
26
23
|
end
|
27
24
|
end
|
28
25
|
end
|
data/lib/hash_out/version.rb
CHANGED
data/lib/init_attrs.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
module InitAttrs
|
2
|
+
module ClassMethods
|
3
|
+
def init_accessor name, procedure=nil, &block
|
4
|
+
register_attr_with_type :attr_accessor, name, procedure || block
|
5
|
+
end
|
6
|
+
|
7
|
+
def init_reader name, procedure=nil, &block
|
8
|
+
register_attr_with_type :attr_reader, name, procedure || block
|
9
|
+
end
|
10
|
+
|
11
|
+
def new *args
|
12
|
+
@instance = super
|
13
|
+
set_ivars
|
14
|
+
@instance
|
15
|
+
end
|
16
|
+
|
17
|
+
def register_attr_with_type type, name, procedure
|
18
|
+
register_attr name, procedure
|
19
|
+
send type, name
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def register_attr name, procedure
|
25
|
+
attrs.merge! "#{name}" => procedure
|
26
|
+
end
|
27
|
+
|
28
|
+
def attrs
|
29
|
+
@attrs ||= {}
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_ivars
|
33
|
+
attrs.each_pair do |name, procedure|
|
34
|
+
@instance.instance_variable_set "@#{name}", value(procedure)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def value procedure
|
39
|
+
@instance.instance_exec &procedure
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.included base
|
44
|
+
base.extend ClassMethods
|
45
|
+
end
|
46
|
+
end
|
data/lib/last_call.rb
CHANGED
@@ -0,0 +1,59 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe 'compatibility with delegators' do
|
4
|
+
require 'forwardable'
|
5
|
+
|
6
|
+
class FreshPrince
|
7
|
+
extend Forwardable
|
8
|
+
include HashOut
|
9
|
+
|
10
|
+
def_delegator :@aww, :to_sym, :aww
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@aww = 'yeah'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'it keeps methods written by Forwardable if delegators are not excluded' do
|
18
|
+
fresh_prince = FreshPrince.new
|
19
|
+
hash_out = { aww: :yeah }
|
20
|
+
|
21
|
+
expect(fresh_prince.hash_out).to_equal hash_out
|
22
|
+
end
|
23
|
+
|
24
|
+
class Clarissa
|
25
|
+
extend Forwardable
|
26
|
+
include HashOut
|
27
|
+
|
28
|
+
exclude_delegators_from_hash_out
|
29
|
+
|
30
|
+
def_delegator :@cool, :upcase
|
31
|
+
def_delegator :@guys, :downcase, :lowercase_guys
|
32
|
+
def_delegators :@alright, :to_s
|
33
|
+
|
34
|
+
def initialize
|
35
|
+
@cool = 'cool'
|
36
|
+
@guys = 'GUYS'
|
37
|
+
@alright = :alright
|
38
|
+
end
|
39
|
+
|
40
|
+
def hey
|
41
|
+
upcase
|
42
|
+
end
|
43
|
+
|
44
|
+
def sup
|
45
|
+
lowercase_guys
|
46
|
+
end
|
47
|
+
|
48
|
+
def alright
|
49
|
+
to_s
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'is ignores methods written by Forwardable if delegators are excluded' do
|
54
|
+
clarissa = Clarissa.new
|
55
|
+
hash_out = { hey: 'COOL', sup: 'guys', alright: 'alright' }
|
56
|
+
|
57
|
+
expect(clarissa.hash_out).to_equal hash_out
|
58
|
+
end
|
59
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hash_out
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dave Jachimiak
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-08-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -54,13 +54,18 @@ files:
|
|
54
54
|
- hash_out.gemspec
|
55
55
|
- lib/hash_out.rb
|
56
56
|
- lib/hash_out/call_registry.rb
|
57
|
+
- lib/hash_out/delegator_excludable.rb
|
58
|
+
- lib/hash_out/delegator_registry.rb
|
57
59
|
- lib/hash_out/excludable.rb
|
58
60
|
- lib/hash_out/hasher.rb
|
59
61
|
- lib/hash_out/object_wrapper.rb
|
62
|
+
- lib/hash_out/object_wrapper/delegated.rb
|
60
63
|
- lib/hash_out/version.rb
|
64
|
+
- lib/init_attrs.rb
|
61
65
|
- lib/last_call.rb
|
62
66
|
- spec/features/ambiguous_caller_spec.rb
|
63
67
|
- spec/features/attribute_mutation_between_hash_out_calls_spec.rb
|
68
|
+
- spec/features/compatible_with_delegators_spec.rb
|
64
69
|
- spec/features/exclude_from_hash_out_spec.rb
|
65
70
|
- spec/features/objects_methods_that_call_hash_out_spec.rb
|
66
71
|
- spec/features/objects_methods_with_arguments_spec.rb
|
@@ -87,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
92
|
version: '0'
|
88
93
|
requirements: []
|
89
94
|
rubyforge_project:
|
90
|
-
rubygems_version: 2.0.
|
95
|
+
rubygems_version: 2.0.6
|
91
96
|
signing_key:
|
92
97
|
specification_version: 4
|
93
98
|
summary: 'hash_out adds the #hash_out method to your class'' instance. It returns
|
@@ -95,9 +100,11 @@ summary: 'hash_out adds the #hash_out method to your class'' instance. It return
|
|
95
100
|
test_files:
|
96
101
|
- spec/features/ambiguous_caller_spec.rb
|
97
102
|
- spec/features/attribute_mutation_between_hash_out_calls_spec.rb
|
103
|
+
- spec/features/compatible_with_delegators_spec.rb
|
98
104
|
- spec/features/exclude_from_hash_out_spec.rb
|
99
105
|
- spec/features/objects_methods_that_call_hash_out_spec.rb
|
100
106
|
- spec/features/objects_methods_with_arguments_spec.rb
|
101
107
|
- spec/features/objects_private_methods_spec.rb
|
102
108
|
- spec/features/objects_public_methods_spec.rb
|
103
109
|
- spec/spec_helper.rb
|
110
|
+
has_rdoc:
|