method_cacheable 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.3
1
+ 0.0.4
@@ -87,55 +87,95 @@ module MethodCacheable
87
87
  end
88
88
 
89
89
  class MethodCache
90
- attr_accessor :caller_object, :method, :args, :options, :cache_operation
91
-
92
- def initialize(caller_object, *method_cache_args)
93
- cache_operation = method_cache_args.map {|x| x if x.is_a? Symbol }.compact.first
94
- options = method_cache_args.map {|x| x if x.is_a? Hash }.compact.first
95
- self.cache_operation = cache_operation||:fetch
96
- self.options = options
97
- self.caller_object = caller_object
90
+ attr_accessor :caller, :method, :args, :options, :cache_operation
91
+
92
+ def initialize(caller, *method_cache_args)
93
+ self.caller = caller
94
+ self.cache_operation = method_cache_args.map {|x| x if x.is_a? Symbol }.compact.first||:fetch
95
+ self.options = method_cache_args.map {|x| x if x.is_a? Hash }.compact.first
96
+ end
97
+
98
+ # Calls the cache based on the given cache_operation
99
+ # @param [Hash] options Options are passed to the cache store
100
+ # @see http://api.rubyonrails.org/classes/ActionController/Caching.html#method-i-cache Rails.cache documentation
101
+ def call
102
+ case cache_operation
103
+ when :fetch
104
+ MethodCacheable.store.fetch(key, options) do
105
+ send_to_caller
106
+ end
107
+ when :read
108
+ read(method, args)
109
+ when :write
110
+ write(method, args) do
111
+ send_to_caller
112
+ end
113
+ end
114
+ end
115
+
116
+ def send_to_caller
117
+ caller.send method.to_sym, *args
118
+ end
119
+
120
+ def write(method, *args, &block)
121
+ val = block.call
122
+ MethodCacheable.store.write(key, val, options)
123
+ end
124
+
125
+ def read(method, *args)
126
+ MethodCacheable.store.read(key, options)
127
+ end
128
+
129
+ def for(method , *args)
130
+ self.method = method
131
+ self.args = args
132
+ self
98
133
  end
99
134
 
100
135
  # Uses keytar to create a key based on the method and caller if no method_key exits
101
136
  # @see http://github.com/schneems/keytar Keytar, it builds keys
137
+ #
138
+ # Method and arguement can optionally be supplied
139
+ #
102
140
  # @return the key used to set the cache
103
141
  # @example
104
142
  # cache = User.find(263619).cache # => #<MethodCacheable::MethodCache ... >
105
143
  # cache.method = "foo" # => "foo"
106
144
  # cache.key # => "users:foo:263619"
107
- def key
108
- key_method = "#{method}_key".to_sym
109
- key = caller_object.send key_method, *args if caller_object.respond_to? key_method
110
- key ||= caller_object.build_key(:name => method, :args => args)
145
+ def key(tmp_method = nil, *tmp_args)
146
+ tmp_method ||= method
147
+ tmp_args ||= args
148
+ key_method = "#{tmp_method}_key".to_sym
149
+ key = caller.send key_method, *tmp_args if caller.respond_to? key_method
150
+ key ||= caller.build_key(:name => tmp_method, :args => tmp_args)
111
151
  end
112
152
 
113
- # Calls the cache based on the given cache_operation
114
- # @param [Hash] options Options are passed to the cache store
115
- # @see http://api.rubyonrails.org/classes/ActionController/Caching.html#method-i-cache Rails.cache documentation
116
- def call_cache_operation(options = {})
117
- if cache_operation == :fetch
118
- MethodCacheable.store.fetch(key, options) do
119
- caller_object.send method.to_sym, *args
120
- end
121
- elsif cache_operation == :read
122
- MethodCacheable.store.read(key, options)
123
- elsif cache_operation == :write
124
- val = caller_object.send method.to_sym, *args
125
- MethodCacheable.store.write(key, val, options)
126
- end
153
+ # Removes the current key from the cache store
154
+ def delete(method, *args)
155
+ self.method = method
156
+ self.args = args
157
+ MethodCacheable.store.delete(key, options)
158
+ end
159
+
160
+ # Checks to see if the key exists in the cache store
161
+ # @return [boolean]
162
+ def exist?(method, *args)
163
+ self.method = method
164
+ self.args = args
165
+ MethodCacheable.store.exist?(key)
127
166
  end
167
+ alias :exists? :exist?
128
168
 
129
- # Methods caught by method_missing are passed to the caller_object and used to :write, :read, or :fetch from the cache
169
+ # Methods caught by method_missing are passed to the caller and used to :write, :read, or :fetch from the cache
130
170
  #
131
171
  # @see MethodCacheable#cache
132
172
  def method_missing(method, *args, &blk)
133
- if caller_object.respond_to? method
134
- self.method = method
135
- self.args = args
136
- call_cache_operation(options)
173
+ self.method = method
174
+ self.args = args
175
+ if caller.respond_to? method
176
+ call
137
177
  else
138
- super
178
+ send_to_caller
139
179
  end
140
180
  end
141
181
  end
@@ -5,15 +5,14 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "method_cacheable"
8
- s.version = "0.0.3"
8
+ s.version = "0.0.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Schneems"]
12
- s.date = "2011-12-12"
12
+ s.date = "2011-12-29"
13
13
  s.description = "\n Cache methods quickly and easily\n "
14
14
  s.email = "richard.schneeman@gmail.com"
15
15
  s.files = [
16
- ".rvmrc",
17
16
  ".yardoc/checksums",
18
17
  ".yardoc/objects/root.dat",
19
18
  ".yardoc/proxy_types",
data/readme.md CHANGED
@@ -5,6 +5,9 @@ Cache method calls and speed up your Ruby on Rails application with MethodCachea
5
5
  Method Cacheable
6
6
  ============
7
7
 
8
+ In your Model include `MethodCacheable`
9
+
10
+ app/models/user.rb
8
11
  ``` ruby
9
12
  class User < ActiveRecord::Base
10
13
  include MethodCacheable
@@ -16,7 +19,11 @@ Method Cacheable
16
19
  return val
17
20
  end
18
21
  end
22
+ ```
23
+
24
+ Then use the `#cache` method to fetch results from cache when available
19
25
 
26
+ ```
20
27
  user = User.last
21
28
 
22
29
  # Call User#expensive_method normally
@@ -45,6 +52,15 @@ in your Gemfile
45
52
 
46
53
  gem 'method_cacheable'
47
54
 
55
+ In an initializer tell MethodCacheable to use the Rails.cache backend. You can use any object here that responds to `#write`, `#read`, and `#fetch`
56
+
57
+ initializers/method_cacheable.rb
58
+ ```ruby
59
+ MethodCacheable.config do |config|
60
+ config.store = Rails.cache
61
+ end
62
+ ```
63
+
48
64
  then in your models
49
65
 
50
66
  include MethodCacheable
@@ -105,4 +121,8 @@ Fork away. If you want to chat about a feature idea, or a question you can find
105
121
 
106
122
  licensed under MIT License
107
123
  Copyright (c) 2011 Schneems. See LICENSE.txt for
108
- further details.
124
+ further details.
125
+
126
+
127
+
128
+
@@ -2,36 +2,70 @@ require 'spec_helper'
2
2
 
3
3
 
4
4
  describe MethodCacheable::MethodCache do
5
- before(:all) do
6
- @user = User.new
7
- end
8
5
 
9
6
  before(:each) do
10
7
  @uniq ||= 0
11
8
  @uniq += 1
12
9
  end
13
10
 
11
+ let(:user) { User.new }
12
+
13
+ describe 'write & read' do
14
+ it 'lets us write & read arbitrary items to the cache' do
15
+ symbol = :arbitrary_entry
16
+ arbitrary_string = "whatever"
17
+ user.cache.write(symbol) {arbitrary_string}
18
+ user.cache.read(symbol).should == arbitrary_string
19
+ end
20
+
21
+ end
22
+
23
+ describe 'key' do
24
+ it 'returns the key' do
25
+ user.cache.key(:foo).should == "users:foo:#{user.id}"
26
+ end
27
+ end
28
+
29
+ describe 'exists?' do
30
+ it 'returns false if the object has not been cached' do
31
+ user.cache.exist?(:new_method).should be_false
32
+ end
33
+
34
+ it 'returns true if the object has been cached' do
35
+ user.cache(:write).foo
36
+ user.cache.exist?(:foo).should be_true
37
+ end
38
+ end
39
+
40
+ describe 'delete' do
41
+ it 'sends delete to underlying cache object' do
42
+ user.cache.delete(:foo)
43
+ user.cache.exist?(:foo).should be_false
44
+ end
45
+ end
46
+
47
+
14
48
  describe 'initialize' do
15
49
  it 'saves caller' do
16
- @user.cache.caller_object.should eq(@user)
50
+ user.cache.caller.should == user
17
51
  end
18
52
 
19
53
  it 'saves cache_method' do
20
54
  cache_method = :fetch
21
- @user.cache(cache_method).cache_operation.should eq(cache_method)
55
+ user.cache(cache_method).cache_operation.should == cache_method
22
56
  end
23
57
 
24
58
  it 'saves options' do
25
59
  options = {:foo => "bar"}
26
- @user.cache(options).options.should eq(options)
60
+ user.cache(options).options.should == options
27
61
  end
28
62
 
29
63
  it 'saves options and cache_method' do
30
64
  cache_method = :write
31
65
  options = {:foo => "bar"}
32
- cache = @user.cache(cache_method, options)
33
- cache.options.should eq(options)
34
- cache.cache_operation.should eq(cache_method)
66
+ cache = user.cache(cache_method, options)
67
+ cache.options.should == options
68
+ cache.cache_operation.should == cache_method
35
69
  end
36
70
  end
37
71
  end
@@ -2,8 +2,9 @@ require 'spec_helper'
2
2
 
3
3
 
4
4
  describe MethodCacheable do
5
+ let(:user) { User.new }
6
+
5
7
  before(:each) do
6
- @user = User.new
7
8
  @uniq ||= 0
8
9
  @uniq += 1
9
10
  end
@@ -12,41 +13,41 @@ describe MethodCacheable do
12
13
  describe 'calling a cached method' do
13
14
  describe 'fetch' do
14
15
  it 'should return the result of the normal method' do
15
- @user.cache.foo(@uniq).should == @user.foo(@uniq)
16
+ user.cache.foo(@uniq).should == user.foo(@uniq)
16
17
  end
17
18
 
18
19
  it 'should bypass the normal method if the cache is written' do
19
- @user.cache(:write).foo(@uniq)
20
- @user.should_not_receive(:foo)
21
- @user.cache(:fetch).foo(@uniq)
20
+ user.cache(:write).foo(@uniq)
21
+ user.should_not_receive(:foo)
22
+ user.cache(:fetch).foo(@uniq)
22
23
  end
23
24
 
24
25
  it 'should bypass the normal method if the cache has been fetched before' do
25
- @user.cache(:fetch).foo(@uniq)
26
- @user.should_not_receive(:foo)
27
- @user.cache(:fetch).foo(@uniq)
26
+ user.cache(:fetch).foo(@uniq)
27
+ user.should_not_receive(:foo)
28
+ user.cache(:fetch).foo(@uniq)
28
29
  end
29
30
 
30
31
  it 'should call the normal method if the cache has been not fetched before' do
31
- @user.should_receive(:foo)
32
- @user.cache(:fetch).foo(@uniq)
32
+ user.should_receive(:foo)
33
+ user.cache(:fetch).foo(@uniq)
33
34
  end
34
35
 
35
36
  it 'should call the normal method if the cache has been not fetched before' do
36
- @user.should_receive(:foo)
37
- @user.cache.foo(@uniq)
37
+ user.should_receive(:foo)
38
+ user.cache.foo(@uniq)
38
39
  end
39
40
 
40
41
  end
41
42
 
42
43
  describe 'read' do
43
44
  it 'read should return nil if cache has not been set yet' do
44
- @user.cache(:read).foo(@uniq).should eq(nil)
45
+ user.cache(:read).foo(@uniq).should == nil
45
46
  end
46
47
 
47
48
  it 'read should return value if cache has been set' do
48
- result = @user.cache.foo(@uniq)
49
- @user.cache(:read).foo(@uniq).should eq(result)
49
+ result = user.cache.foo(@uniq)
50
+ user.cache(:read).foo(@uniq).should == result
50
51
  end
51
52
  end
52
53
  end
@@ -10,21 +10,36 @@ class Rails
10
10
  self
11
11
  end
12
12
 
13
- def self.fetch(key, options, &block)
13
+ # not quite the same as deleting but it will do
14
+ def self.delete(key, options = {})
15
+ eval("@#{key.gsub(':', '_')} = nil")
16
+ end
17
+
18
+ def self.exist?(key)
19
+ !eval("@#{key.gsub(':', '_')}").nil?
20
+ end
21
+
22
+ def self.fetch(key, options = {}, &block)
14
23
  eval("@#{key.gsub(':', '_')} ||= block.call")
15
24
  end
16
25
 
17
- def self.write(key, val, options, &block)
26
+ def self.write(key, val, options = {}, &block)
18
27
  eval("@#{key.gsub(':', '_')} = val")
19
28
  end
20
29
 
21
- def self.read(key, options)
30
+ def self.read(key, options = {})
22
31
  eval("@#{key.gsub(':', '_')}")
23
32
  end
24
33
  end
25
34
 
26
-
27
35
  require 'method_cacheable'
36
+
37
+
38
+ MethodCacheable.config do |config|
39
+ config.store = Rails.cache
40
+ end
41
+
42
+
28
43
  class User
29
44
  include MethodCacheable
30
45
  define_keys :foo
metadata CHANGED
@@ -1,162 +1,121 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: method_cacheable
3
- version: !ruby/object:Gem::Version
4
- hash: 25
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 0
9
- - 3
10
- version: 0.0.3
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Schneems
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-12-12 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
21
- version_requirements: &id001 !ruby/object:Gem::Requirement
22
- none: false
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- hash: 3
27
- segments:
28
- - 0
29
- version: "0"
12
+ date: 2011-12-29 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
30
15
  name: activesupport
31
- prerelease: false
32
- type: :runtime
33
- requirement: *id001
34
- - !ruby/object:Gem::Dependency
35
- version_requirements: &id002 !ruby/object:Gem::Requirement
16
+ requirement: &70212263196980 !ruby/object:Gem::Requirement
36
17
  none: false
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- hash: 3
41
- segments:
42
- - 0
43
- version: "0"
44
- name: keytar
45
- prerelease: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
46
22
  type: :runtime
47
- requirement: *id002
48
- - !ruby/object:Gem::Dependency
49
- version_requirements: &id003 !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ version_requirements: *70212263196980
25
+ - !ruby/object:Gem::Dependency
26
+ name: keytar
27
+ requirement: &70212263195260 !ruby/object:Gem::Requirement
50
28
  none: false
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- hash: 3
55
- segments:
56
- - 0
57
- version: "0"
58
- name: yard
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
59
34
  prerelease: false
60
- type: :development
61
- requirement: *id003
62
- - !ruby/object:Gem::Dependency
63
- version_requirements: &id004 !ruby/object:Gem::Requirement
35
+ version_requirements: *70212263195260
36
+ - !ruby/object:Gem::Dependency
37
+ name: yard
38
+ requirement: &70212263175320 !ruby/object:Gem::Requirement
64
39
  none: false
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- hash: 3
69
- segments:
70
- - 0
71
- version: "0"
72
- name: rdiscount
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
73
45
  prerelease: false
46
+ version_requirements: *70212263175320
47
+ - !ruby/object:Gem::Dependency
48
+ name: rdiscount
49
+ requirement: &70212263173780 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
74
55
  type: :development
75
- requirement: *id004
76
- - !ruby/object:Gem::Dependency
77
- version_requirements: &id005 !ruby/object:Gem::Requirement
56
+ prerelease: false
57
+ version_requirements: *70212263173780
58
+ - !ruby/object:Gem::Dependency
59
+ name: rake
60
+ requirement: &70212263171900 !ruby/object:Gem::Requirement
78
61
  none: false
79
- requirements:
62
+ requirements:
80
63
  - - ~>
81
- - !ruby/object:Gem::Version
82
- hash: 49
83
- segments:
84
- - 0
85
- - 8
86
- - 7
64
+ - !ruby/object:Gem::Version
87
65
  version: 0.8.7
88
- name: rake
89
- prerelease: false
90
66
  type: :development
91
- requirement: *id005
92
- - !ruby/object:Gem::Dependency
93
- version_requirements: &id006 !ruby/object:Gem::Requirement
67
+ prerelease: false
68
+ version_requirements: *70212263171900
69
+ - !ruby/object:Gem::Dependency
70
+ name: jeweler
71
+ requirement: &70212263170520 !ruby/object:Gem::Requirement
94
72
  none: false
95
- requirements:
73
+ requirements:
96
74
  - - ~>
97
- - !ruby/object:Gem::Version
98
- hash: 7
99
- segments:
100
- - 1
101
- - 5
102
- - 2
75
+ - !ruby/object:Gem::Version
103
76
  version: 1.5.2
104
- name: jeweler
105
- prerelease: false
106
77
  type: :development
107
- requirement: *id006
108
- - !ruby/object:Gem::Dependency
109
- version_requirements: &id007 !ruby/object:Gem::Requirement
110
- none: false
111
- requirements:
112
- - - ">="
113
- - !ruby/object:Gem::Version
114
- hash: 3
115
- segments:
116
- - 0
117
- version: "0"
118
- name: autotest-standalone
119
78
  prerelease: false
120
- type: :development
121
- requirement: *id007
122
- - !ruby/object:Gem::Dependency
123
- version_requirements: &id008 !ruby/object:Gem::Requirement
79
+ version_requirements: *70212263170520
80
+ - !ruby/object:Gem::Dependency
81
+ name: autotest-standalone
82
+ requirement: &70212263169000 !ruby/object:Gem::Requirement
124
83
  none: false
125
- requirements:
126
- - - ">="
127
- - !ruby/object:Gem::Version
128
- hash: 3
129
- segments:
130
- - 0
131
- version: "0"
132
- name: autotest-growl
133
- prerelease: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
134
88
  type: :development
135
- requirement: *id008
136
- - !ruby/object:Gem::Dependency
137
- version_requirements: &id009 !ruby/object:Gem::Requirement
89
+ prerelease: false
90
+ version_requirements: *70212263169000
91
+ - !ruby/object:Gem::Dependency
92
+ name: autotest-growl
93
+ requirement: &70212263166500 !ruby/object:Gem::Requirement
138
94
  none: false
139
- requirements:
140
- - - ">="
141
- - !ruby/object:Gem::Version
142
- hash: 3
143
- segments:
144
- - 0
145
- version: "0"
146
- name: rspec
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
147
100
  prerelease: false
101
+ version_requirements: *70212263166500
102
+ - !ruby/object:Gem::Dependency
103
+ name: rspec
104
+ requirement: &70212263164700 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
148
110
  type: :development
149
- requirement: *id009
150
- description: "\n Cache methods quickly and easily\n "
111
+ prerelease: false
112
+ version_requirements: *70212263164700
113
+ description: ! "\n Cache methods quickly and easily\n "
151
114
  email: richard.schneeman@gmail.com
152
115
  executables: []
153
-
154
116
  extensions: []
155
-
156
117
  extra_rdoc_files: []
157
-
158
- files:
159
- - .rvmrc
118
+ files:
160
119
  - .yardoc/checksums
161
120
  - .yardoc/objects/root.dat
162
121
  - .yardoc/proxy_types
@@ -190,39 +149,34 @@ files:
190
149
  - spec/method_cacheable_spec.rb
191
150
  - spec/spec_helper.rb
192
151
  homepage: http://github.com/Schnems/method_cacheable
193
- licenses:
152
+ licenses:
194
153
  - MIT
195
154
  post_install_message:
196
155
  rdoc_options: []
197
-
198
- require_paths:
156
+ require_paths:
199
157
  - lib
200
- required_ruby_version: !ruby/object:Gem::Requirement
158
+ required_ruby_version: !ruby/object:Gem::Requirement
201
159
  none: false
202
- requirements:
203
- - - ">="
204
- - !ruby/object:Gem::Version
205
- hash: 3
206
- segments:
160
+ requirements:
161
+ - - ! '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ segments:
207
165
  - 0
208
- version: "0"
209
- required_rubygems_version: !ruby/object:Gem::Requirement
166
+ hash: 588910908911295363
167
+ required_rubygems_version: !ruby/object:Gem::Requirement
210
168
  none: false
211
- requirements:
212
- - - ">="
213
- - !ruby/object:Gem::Version
214
- hash: 3
215
- segments:
216
- - 0
217
- version: "0"
169
+ requirements:
170
+ - - ! '>='
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
218
173
  requirements: []
219
-
220
174
  rubyforge_project:
221
175
  rubygems_version: 1.8.10
222
176
  signing_key:
223
177
  specification_version: 3
224
178
  summary: Cache methods quickly and easily.
225
- test_files:
179
+ test_files:
226
180
  - spec/method_cacheable/method_cache_spec.rb
227
181
  - spec/method_cacheable_spec.rb
228
182
  - spec/spec_helper.rb
data/.rvmrc DELETED
@@ -1,17 +0,0 @@
1
- ruby_string="ree"
2
- gemset_name="johnny_cache"
3
-
4
- if rvm list strings | grep -q "${ruby_string}" ; then
5
-
6
- rvm use "${ruby_string}@${gemset_name}" --create
7
-
8
- # Complain if bundler isn't installed
9
- if [[ -z "`gem which bundler 2>&1 | grep -v ERROR`" ]]; then
10
- echo "You need bundler:"
11
- echo ""
12
- echo " gem install bundler"
13
- echo ""
14
- fi
15
- else
16
- echo "${ruby_string} was not found, please run 'rvm install ${ruby_string}' and then cd back into the project directory."
17
- fi