caching 0.0.2 → 0.0.3

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.
data/README.md CHANGED
@@ -25,23 +25,36 @@ Or install it yourself as:
25
25
  ## Usage
26
26
 
27
27
  class Model
28
- extend Caching
29
-
30
- cache :slow_method, :other_slow_method
31
-
32
28
  def slow_method
33
29
  ...
34
30
  end
31
+ cache_method :slow_method
35
32
 
36
- def other_slow_method
33
+ def slow_method_with_args(*args)
37
34
  ...
38
35
  end
36
+ cache_method :slow_method_with_args
39
37
 
40
38
  def fast_method
41
39
  ...
42
40
  end
43
41
  end
44
42
 
43
+ model = Model.new
44
+
45
+ model.slow_method # => Execute method
46
+ model.slow_method # => Return cached value
47
+
48
+ model.slow_method_with_args 'some value' # => Execute method
49
+ model.slow_method_with_args 'some value' # => Return cached value for argument 'some value'
50
+
51
+ model.slow_method_with_args 1234 # => Execute method
52
+ model.slow_method_with_args 1234 # => Return cached value for argument 1234
53
+
54
+ model.clear_cache :slow_method # => Remove cache only for method slow_method
55
+
56
+ model.clear_cache # => Remove cache for all cached methods
57
+
45
58
  ## Contributing
46
59
 
47
60
  1. Fork it
@@ -1,3 +1,3 @@
1
1
  module Caching
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/lib/caching.rb CHANGED
@@ -2,23 +2,41 @@ Dir["#{File.dirname(__FILE__)}/caching/*.rb"].each { |file| require file }
2
2
 
3
3
  module Caching
4
4
 
5
- def self.extended(klass)
6
- constructor = klass.method :new
5
+ module ClassMethods
7
6
 
8
- klass.define_singleton_method :new do |*args, &block|
9
- instance = constructor.call(*args, &block)
10
- proxy = Proxy.new instance, *@cached_methods
7
+ def cache_method(method)
8
+ alias_method "#{method}_without_cache", method
11
9
 
12
- instance.send :define_singleton_method, :clear_cache do
13
- proxy.clear_cache
10
+ define_method method do |*args, &block|
11
+ method_key = "#{method}_#{Marshal.dump(args)}"
12
+ cached_methods_keys[method] << method_key
13
+ cache_storage.fetch(method_key) { send "#{method}_without_cache", *args, &block }
14
14
  end
15
-
16
- proxy
17
15
  end
16
+
18
17
  end
19
18
 
20
- def cache(*methods)
21
- @cached_methods = (@cached_methods ||= []) | methods.map(&:to_sym).uniq
19
+ module InstanceMethods
20
+
21
+ def cache_storage
22
+ @cache_storage ||= Storage.new
23
+ end
24
+
25
+ def cached_methods_keys
26
+ @cached_methods_keys ||= Hash.new {|h,k| h[k] = []}
27
+ end
28
+
29
+ def clear_cache(*methods)
30
+ method_keys = cached_methods_keys.
31
+ select{ |m,_| methods.include? m }.
32
+ flat_map{ |_,keys| keys }
33
+
34
+ cache_storage.clear *method_keys
35
+ end
36
+
22
37
  end
23
38
 
24
- end
39
+ end
40
+
41
+ Object.send :extend, Caching::ClassMethods
42
+ Object.send :include, Caching::InstanceMethods
data/spec/caching_spec.rb CHANGED
@@ -3,37 +3,36 @@ require 'minitest_helper'
3
3
  describe Caching do
4
4
 
5
5
  class Cachable
6
- extend Caching
7
- cache :slow_method, :other_slow_method
8
6
 
9
7
  def initialize
10
8
  @slow_method = 0
11
- @other_slow_method = 0
9
+ @slow_method_with_args = 0
12
10
  @fast_method = 0
13
11
  end
14
12
 
15
13
  def slow_method
16
14
  @slow_method += 1
17
15
  end
16
+ cache_method :slow_method
18
17
 
19
- def other_slow_method
20
- @other_slow_method += 1
18
+ def slow_method_with_args(arg)
19
+ @slow_method_with_args += 1
21
20
  end
21
+ cache_method :slow_method_with_args
22
22
 
23
23
  def fast_method
24
24
  @fast_method += 1
25
25
  end
26
26
 
27
- def reset
28
- clear_cache
29
- end
30
27
  end
31
28
 
29
+
32
30
  it 'Cache methods' do
33
31
  object = Cachable.new
34
32
 
35
33
  3.times { object.slow_method.must_equal 1 }
36
- 3.times { object.other_slow_method.must_equal 1 }
34
+ 3.times { object.slow_method_with_args([1]).must_equal 1 }
35
+ 3.times { object.slow_method_with_args('text').must_equal 2 }
37
36
  object.fast_method.must_equal 1
38
37
  object.fast_method.must_equal 2
39
38
  end
@@ -42,36 +41,41 @@ describe Caching do
42
41
  object = Cachable.new
43
42
 
44
43
  3.times { object.slow_method.must_equal 1 }
45
- 3.times { object.other_slow_method.must_equal 1 }
44
+ 3.times { object.slow_method_with_args([1]).must_equal 1 }
45
+ 3.times { object.slow_method_with_args('text').must_equal 2 }
46
46
 
47
47
  object.clear_cache
48
48
 
49
49
  object.slow_method.must_equal 2
50
- object.other_slow_method.must_equal 2
50
+ object.slow_method_with_args(3).must_equal 3
51
51
  end
52
52
 
53
53
  it 'Clear cache for specific method' do
54
54
  object = Cachable.new
55
55
 
56
56
  3.times { object.slow_method.must_equal 1 }
57
- 3.times { object.other_slow_method.must_equal 1 }
57
+ 3.times { object.slow_method_with_args([1]).must_equal 1 }
58
+ 3.times { object.slow_method_with_args('text').must_equal 2 }
58
59
 
59
60
  object.clear_cache :slow_method
60
61
 
61
62
  object.slow_method.must_equal 2
62
- object.other_slow_method.must_equal 1
63
+ object.slow_method_with_args([1]).must_equal 1
64
+ object.slow_method_with_args('text').must_equal 2
63
65
  end
64
66
 
65
- it 'Clear cache inside object' do
67
+ it 'Clear cache for specific method with arguments' do
66
68
  object = Cachable.new
67
69
 
68
70
  3.times { object.slow_method.must_equal 1 }
69
- 3.times { object.other_slow_method.must_equal 1 }
71
+ 3.times { object.slow_method_with_args([1]).must_equal 1 }
72
+ 3.times { object.slow_method_with_args('text').must_equal 2 }
70
73
 
71
- object.reset
74
+ object.clear_cache :slow_method_with_args
72
75
 
73
- object.slow_method.must_equal 2
74
- object.other_slow_method.must_equal 2
76
+ object.slow_method.must_equal 1
77
+ object.slow_method_with_args([1]).must_equal 3
78
+ object.slow_method_with_args('text').must_equal 4
75
79
  end
76
80
 
77
81
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: caching
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-24 00:00:00.000000000 Z
12
+ date: 2013-05-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -107,13 +107,11 @@ files:
107
107
  - Rakefile
108
108
  - caching.gemspec
109
109
  - lib/caching.rb
110
- - lib/caching/proxy.rb
111
110
  - lib/caching/storage.rb
112
111
  - lib/caching/version.rb
113
112
  - spec/caching_spec.rb
114
113
  - spec/coverage_helper.rb
115
114
  - spec/minitest_helper.rb
116
- - spec/proxy_spec.rb
117
115
  - spec/storage_spec.rb
118
116
  homepage: https://github.com/gabynaiman/caching
119
117
  licenses:
@@ -144,6 +142,5 @@ test_files:
144
142
  - spec/caching_spec.rb
145
143
  - spec/coverage_helper.rb
146
144
  - spec/minitest_helper.rb
147
- - spec/proxy_spec.rb
148
145
  - spec/storage_spec.rb
149
146
  has_rdoc:
data/lib/caching/proxy.rb DELETED
@@ -1,25 +0,0 @@
1
- module Caching
2
- class Proxy
3
-
4
- instance_methods.each { |m| undef_method m unless m =~ /(^__|^send$|^object_id$)/ }
5
-
6
- def initialize(target, *methods)
7
- @target = target
8
- @methods = methods.map(&:to_sym)
9
- @storage = Storage.new
10
- end
11
-
12
- def method_missing(method, *args, &block)
13
- if @methods.include? method.to_sym
14
- @storage.fetch(method) { @target.send(method, *args, &block) }
15
- else
16
- @target.send(method, *args, &block)
17
- end
18
- end
19
-
20
- def clear_cache(*methods)
21
- @storage.clear *methods
22
- end
23
-
24
- end
25
- end
data/spec/proxy_spec.rb DELETED
@@ -1,59 +0,0 @@
1
- require 'minitest_helper'
2
-
3
- describe Caching::Proxy do
4
-
5
- class Fake
6
- attr_reader :x, :y
7
-
8
- def initialize
9
- @x = 0
10
- @y = 0
11
- end
12
-
13
- def next_x
14
- @x += 1
15
- end
16
-
17
- def next_y
18
- @y += 1
19
- end
20
- end
21
-
22
- it 'Cache specific method' do
23
- object = Fake.new
24
- proxy = Caching::Proxy.new object, :next_x
25
-
26
- proxy.next_x.must_equal 1
27
- proxy.next_x.must_equal 1
28
-
29
- proxy.next_y.must_equal 1
30
- proxy.next_y.must_equal 2
31
- end
32
-
33
- it 'Clear cache for all methods' do
34
- object = Fake.new
35
- proxy = Caching::Proxy.new object, :next_x, :next_y
36
-
37
- 3.times{ proxy.next_x.must_equal 1 }
38
- 3.times{ proxy.next_y.must_equal 1 }
39
-
40
- proxy.clear_cache
41
-
42
- proxy.next_x.must_equal 2
43
- proxy.next_y.must_equal 2
44
- end
45
-
46
- it 'Clear cache for specific method' do
47
- object = Fake.new
48
- proxy = Caching::Proxy.new object, :next_x, :next_y
49
-
50
- 3.times{ proxy.next_x.must_equal 1 }
51
- 3.times{ proxy.next_y.must_equal 1 }
52
-
53
- proxy.clear_cache :next_x
54
-
55
- proxy.next_x.must_equal 2
56
- proxy.next_y.must_equal 1
57
- end
58
-
59
- end