hash_out 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 27081d531afa436f0f54a81a4a23365562040c33
4
- data.tar.gz: fe5c98956a7947cf8845b9ce8329195b5a3ec0a6
3
+ metadata.gz: 18c9acb44220caec2192ec5e88db339e3ee2d206
4
+ data.tar.gz: bd0dda418d17c604f4257f3b15fe8152f0addbee
5
5
  SHA512:
6
- metadata.gz: 12218032e2a88287657a84bfe5dc9864f89dade6d5043b636cb29ad804b9f132a83893b959ae7c0f003e2e7c8cf55e92289ce88dfc61c4a065adf1b82a260449
7
- data.tar.gz: 18f44cd905066a39aac9f46740ce86234674704892b3a1e8c59e92e0ee655f970875e88baa3c30b99814d32fb88e7525ba47dc6429ffdbecbefc94f0b777f2d1
6
+ metadata.gz: 11961d83bcc9a1441c0e3351e503b53e614fd7c59a150d0a2a3e93638e8bfce6dc7ca6112479e9d847ef2c60e9cd4fba332a63f4b7cb005108399c3b4fe4003a
7
+ data.tar.gz: 932cb9c2a0c88e881b0b9f528211f6eb49c4b35f01fbf34057c444f1b7a5389d5abe47875c61bb4093fc94517a1503b8925f41c15a27c791611395e08d4ba013
data/.travis.yml CHANGED
@@ -4,5 +4,4 @@ rvm:
4
4
  - 1.9.3
5
5
  - 2.0.0
6
6
  - rbx-19mode
7
- - jruby-19mode
8
7
  script: bundle exec rake
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hash_out (0.1.4)
4
+ hash_out (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
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.1'
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
- attr_reader :hash_out_caller
2
+ class CallRegistry < Struct.new :hash_out_caller
3
+ include InitAttrs
4
4
 
5
- def initialize hash_out_caller
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
- @times_called += 1
8
+ self.times_called += 1
12
9
  end
13
10
 
14
11
  def delete_caller_from hash
15
- hash.delete hash_out_caller if internal_call?
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
- @times_called > 1
18
+ times_called > 1
22
19
  end
23
20
  end
24
21
  end
@@ -0,0 +1,11 @@
1
+ require 'hash_out/excludable'
2
+
3
+ module HashOut
4
+ module DelegatorExcludable
5
+ include Excludable
6
+
7
+ def exclusions
8
+ @exclusions ||= self.class.delegators
9
+ end
10
+ end
11
+ 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
@@ -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 prepare_exclusions methods
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 delete_exclusions methods
16
- exclusions.each { |method| methods.delete method }
24
+ def delete_exclusions_from methods
25
+ methods.delete_if { |method| exclusions.include? method }
17
26
  end
18
27
  end
19
28
  end
@@ -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 Forwardable
5
+ extend Forwardable
6
+ include InitAttrs
7
7
 
8
- def_delegator :object, :excludable, :excludable_obj
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
- @hashable_methods = object.public_methods_requiring_no_args
20
- call_registry.delete_caller_from @hashable_methods
21
- end
21
+ methods = hashable_methods
22
22
 
23
- def delete_excluded_methods
24
- excludable_obj.prepare_exclusions @hashable_methods
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
- @hashable_methods.map do |method|
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
- extend Forwardable
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? m
25
- [-1, 0].include? method(m).arity
21
+ def requires_no_args? method
22
+ [-1, 0].include? method(method).arity
26
23
  end
27
24
  end
28
25
  end
@@ -0,0 +1,9 @@
1
+ require 'hash_out/delegator_excludable'
2
+
3
+ module HashOut
4
+ class ObjectWrapper
5
+ class Delegated < ObjectWrapper
6
+ init_reader :excludable, ->{ dup.extend DelegatorExcludable }
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  module HashOut
2
- VERSION = '0.1.4'
2
+ VERSION = '0.2.0'
3
3
  end
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
@@ -1,4 +1,4 @@
1
- module Kernel
1
+ module LastCall
2
2
  def last_call
3
3
  caller[1].match(/`(.*)'/)[1].to_sym
4
4
  end
@@ -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.1.4
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-07-19 00:00:00.000000000 Z
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.2
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: