hash_out 0.1.3 → 0.1.4

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: b9a0ed8ed60004a223c24fb5c5d7dc878ce96de7
4
- data.tar.gz: 49bfa30ee0655b9fbd206dfeef7881a24e9e2a18
3
+ metadata.gz: 27081d531afa436f0f54a81a4a23365562040c33
4
+ data.tar.gz: fe5c98956a7947cf8845b9ce8329195b5a3ec0a6
5
5
  SHA512:
6
- metadata.gz: 41a8055dd2e9f5f7ff7928b8760016d711eeeea3fd01b66adc3b2ab5322a3281098b718249fff71f092186bac3560a54aa014d989d7e30a8da9fb524d6e79e48
7
- data.tar.gz: 7c7aa9a516d33a43ac4edd84de03ba540ca2a990786d8f1b739d254b985c3f94676e79e92116855251ae8817d61eb19cc88bd894a8607be06f7f2a133bd3bba9
6
+ metadata.gz: 12218032e2a88287657a84bfe5dc9864f89dade6d5043b636cb29ad804b9f132a83893b959ae7c0f003e2e7c8cf55e92289ce88dfc61c4a065adf1b82a260449
7
+ data.tar.gz: 18f44cd905066a39aac9f46740ce86234674704892b3a1e8c59e92e0ee655f970875e88baa3c30b99814d32fb88e7525ba47dc6429ffdbecbefc94f0b777f2d1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ### version 0.1.4 - *July 18, 2013*
2
+ * Fixes bug (issue #1): `#exclude_from_hash_out` does not block mutation that may happen in the call.
3
+
4
+ closes #1
5
+
1
6
  ### version 0.1.3 - *July 17, 2013*
2
7
  * Fixes bug: multiple calls to `#hash_out` that are from an internal method infinitely recurse
3
8
  * Fixes bug: method not present in hash when outside caller of `#hash_out` has same name
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hash_out (0.1.2)
4
+ hash_out (0.1.4)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -37,26 +37,39 @@ Movie.new.hash_out
37
37
  # => {:title=>"Fire Walk With Me", :director=>'David Lynch'}
38
38
  ```
39
39
 
40
- To exclude public methods from `#hash_out`, put `exclude_from_hash_out` at the top of them.
40
+ To exclude public methods from `#hash_out`, call the `#exclude_from_hash_out` method in them.
41
+ `#exclude_from_hash_out` blocks any attribute mutation that occurs during a normal call to the
42
+ method.
41
43
 
42
44
  ```ruby
43
45
  require 'hash_out'
44
46
 
45
- class Movie
47
+ class Post
46
48
  include HashOut
47
49
 
50
+ attr_reader :upvotes
51
+
52
+ def initialize
53
+ @upvotes = 1000000
54
+ end
55
+
48
56
  def title
49
- 'Fire Walk With Me'
57
+ 'Twin Peaks fuckin rocks'
50
58
  end
51
59
 
52
- def director
60
+ def upvote
53
61
  exclude_from_hash_out
54
- 'David Lynch'
62
+ @upvotes += 500000
55
63
  end
56
64
  end
57
65
 
58
- Movie.new.hash_out
59
- # => {:title=>"Fire Walk With Me"}
66
+ post = Post.new
67
+ post.hash_out
68
+ # => {:title=>"Twin Peaks fuckin rocks", :upvotes=>1000000}
69
+
70
+ post.upvote
71
+ post.hash_out
72
+ # => {:title=>"Twin Peaks fuckin rocks", :upvotes=>1500000}
60
73
  ```
61
74
 
62
75
  Private methods are ignored.
@@ -0,0 +1,19 @@
1
+ module HashOut
2
+ module Excludable
3
+ def exclusions
4
+ @exclusions ||= []
5
+ end
6
+
7
+ def exclude_from_hash_out
8
+ exclusions.push last_call
9
+ end
10
+
11
+ def prepare_exclusions methods
12
+ methods.each { |method| send method }
13
+ end
14
+
15
+ def delete_exclusions methods
16
+ exclusions.each { |method| methods.delete method }
17
+ end
18
+ end
19
+ end
@@ -1,41 +1,34 @@
1
- require 'set'
1
+ require 'hash_out/excludable'
2
+ require 'forwardable'
2
3
 
3
4
  module HashOut
4
5
  class Hasher < Struct.new :object, :call_registry
5
- def object_to_hash
6
- prepare_hashable_methods
7
- set_hash
8
- delete_exclusions
9
- @hash
10
- end
6
+ extend Forwardable
11
7
 
12
- def exclusions
13
- @exclusions ||= Set.new
14
- end
8
+ def_delegator :object, :excludable, :excludable_obj
15
9
 
16
- def exclude method
17
- exclusions.add method
10
+ def object_to_hash
11
+ prepare_hashable_methods
12
+ delete_excluded_methods
13
+ Hash[hashable_method_value_pairs]
18
14
  end
19
15
 
20
16
  private
21
17
 
22
18
  def prepare_hashable_methods
23
- @hashable_methods = object.send :_methods_requiring_no_args
19
+ @hashable_methods = object.public_methods_requiring_no_args
24
20
  call_registry.delete_caller_from @hashable_methods
25
21
  end
26
22
 
27
- def set_hash
28
- @hash = Hash[hashable_method_value_pairs]
23
+ def delete_excluded_methods
24
+ excludable_obj.prepare_exclusions @hashable_methods
25
+ excludable_obj.delete_exclusions @hashable_methods
29
26
  end
30
27
 
31
28
  def hashable_method_value_pairs
32
29
  @hashable_methods.map do |method|
33
- object.send :_method_value_pair, method
30
+ object.method_value_pair method
34
31
  end
35
32
  end
36
-
37
- def delete_exclusions
38
- exclusions.each { |exclusion| @hash.delete exclusion }
39
- end
40
33
  end
41
34
  end
@@ -0,0 +1,28 @@
1
+ require 'hash_out/excludable'
2
+ require 'forwardable'
3
+
4
+ module HashOut
5
+ class ObjectWrapper < Struct.new :object
6
+ extend Forwardable
7
+
8
+ def_delegators :object, :dup, :public_methods, :send, :method
9
+
10
+ def excludable
11
+ @excludable ||= dup.extend Excludable
12
+ end
13
+
14
+ def public_methods_requiring_no_args
15
+ public_methods(false).select { |method| requires_no_args? method }
16
+ end
17
+
18
+ def method_value_pair method
19
+ [method, send(method)]
20
+ end
21
+
22
+ private
23
+
24
+ def requires_no_args? m
25
+ [-1, 0].include? method(m).arity
26
+ end
27
+ end
28
+ end
@@ -1,3 +1,3 @@
1
1
  module HashOut
2
- VERSION = '0.1.3'
2
+ VERSION = '0.1.4'
3
3
  end
data/lib/hash_out.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'last_call'
2
- require 'hash_out/call_registry'
3
2
  require 'hash_out/hasher'
3
+ require 'hash_out/call_registry'
4
+ require 'hash_out/object_wrapper'
4
5
 
5
6
  module HashOut
6
7
  def hash_out
@@ -8,12 +9,6 @@ module HashOut
8
9
  _hasher.object_to_hash
9
10
  end
10
11
 
11
- protected
12
-
13
- def exclude_from_hash_out
14
- _hasher.exclude last_call
15
- end
16
-
17
12
  private
18
13
 
19
14
  def _register_call hash_out_caller
@@ -25,14 +20,12 @@ module HashOut
25
20
  end
26
21
 
27
22
  def _hasher
28
- @_hasher ||= Hasher.new self, _call_registry
23
+ @_hasher ||= Hasher.new _wrapped_self, _call_registry
29
24
  end
30
25
 
31
- def _methods_requiring_no_args
32
- public_methods(false).select { |m| [-1, 0].include? method(m).arity }
26
+ def _wrapped_self
27
+ @_wrapped_self ||= ObjectWrapper.new self
33
28
  end
34
29
 
35
- def _method_value_pair method
36
- [method, send(method)]
37
- end
30
+ def exclude_from_hash_out; end;
38
31
  end
@@ -1,6 +1,6 @@
1
1
  require_relative '../spec_helper'
2
2
 
3
- describe 'attribute mutation' do
3
+ describe 'attribute mutation between #hash_out calls' do
4
4
  class Ooze
5
5
  include HashOut
6
6
  attr_accessor :color
@@ -20,4 +20,34 @@ describe '#exclude_from_hash_out' do
20
20
 
21
21
  expect(brawler.hash_out).to_equal hash_out
22
22
  end
23
+
24
+ class Lips
25
+ include HashOut
26
+
27
+ def initialize
28
+ @size = :small
29
+ end
30
+
31
+ def botox
32
+ exclude_from_hash_out
33
+ @size = :fat
34
+ end
35
+
36
+ def size
37
+ @size
38
+ end
39
+ end
40
+
41
+ it 'blocks mutation effects below call' do
42
+ lips = Lips.new
43
+ hash_out = { size: :small }
44
+
45
+ expect(lips.hash_out).to_equal hash_out
46
+ end
47
+
48
+ it 'mutates if call is not from #hash_out' do
49
+ lips = Lips.new
50
+ lips.botox
51
+ expect(lips.size).to_equal :fat
52
+ end
23
53
  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.3
4
+ version: 0.1.4
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-18 00:00:00.000000000 Z
11
+ date: 2013-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -54,11 +54,13 @@ files:
54
54
  - hash_out.gemspec
55
55
  - lib/hash_out.rb
56
56
  - lib/hash_out/call_registry.rb
57
+ - lib/hash_out/excludable.rb
57
58
  - lib/hash_out/hasher.rb
59
+ - lib/hash_out/object_wrapper.rb
58
60
  - lib/hash_out/version.rb
59
61
  - lib/last_call.rb
60
62
  - spec/features/ambiguous_caller_spec.rb
61
- - spec/features/attribute_mutation_spec.rb
63
+ - spec/features/attribute_mutation_between_hash_out_calls_spec.rb
62
64
  - spec/features/exclude_from_hash_out_spec.rb
63
65
  - spec/features/objects_methods_that_call_hash_out_spec.rb
64
66
  - spec/features/objects_methods_with_arguments_spec.rb
@@ -92,7 +94,7 @@ summary: 'hash_out adds the #hash_out method to your class'' instance. It return
92
94
  a hash of public method names and values.'
93
95
  test_files:
94
96
  - spec/features/ambiguous_caller_spec.rb
95
- - spec/features/attribute_mutation_spec.rb
97
+ - spec/features/attribute_mutation_between_hash_out_calls_spec.rb
96
98
  - spec/features/exclude_from_hash_out_spec.rb
97
99
  - spec/features/objects_methods_that_call_hash_out_spec.rb
98
100
  - spec/features/objects_methods_with_arguments_spec.rb