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 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: