hash_out 0.1.3 → 0.1.4

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