caching 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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