method_cacheable 0.0.3 → 0.0.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.
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