cache_method 0.1.6 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,7 +1,6 @@
1
1
  *.gem
2
- .bundle
3
2
  Gemfile.lock
4
- pkg/*
5
- rdoc/*
6
- secret.sh
7
3
  .DS_Store
4
+ .yardoc/
5
+ doc/
6
+ .bundle/
data/CHANGELOG ADDED
@@ -0,0 +1,24 @@
1
+ 0.2.0 / 2012-02-29
2
+
3
+ * API changes:
4
+
5
+ * #clear_method_cache -> #cache_method_clear
6
+ * #method_cache_hash -> #as_cache_key (see README)
7
+ * doesn't rely on #hash at all any more (http://numbers.brighterplanet.com/2012/02/29/beware-of-string-hash-being-used-for-cache-keys/)
8
+ * doesn't try to mitigate differences between Ruby 1.8 and 1.9 splats (http://www.ruby-forum.com/topic/98106)
9
+
10
+ * Enhancements
11
+
12
+ * clearer method naming, I think
13
+ * safer determination of cache keys - previously, in effect, args.map(&:to_s) was being used
14
+ * no more autoload
15
+ * remove direct dependency on activesupport
16
+ * tests now run with dalli, green on MRI 1.8, MRI 1.9, and jruby 1.6.7
17
+
18
+ 0.1.7 / yanked!
19
+
20
+ * Bug: used args.map(&:hash) instead of args.map(&:to_s)... which was actually worse because #hash is different across processes.
21
+
22
+ 0.1.6 / November 17, 2011
23
+
24
+ * Last release before CHANGELOG in place
data/Gemfile CHANGED
@@ -1,4 +1,9 @@
1
- source "http://rubygems.org"
1
+ source :rubygems
2
2
 
3
3
  # Specify your gem's dependencies in cache_method.gemspec
4
4
  gemspec
5
+
6
+ # development dependencies
7
+ gem 'rake'
8
+ gem 'dalli'
9
+ gem 'yard'
@@ -1,14 +1,14 @@
1
- = cache_method
1
+ # cache_method
2
2
 
3
- It's like <tt>alias_method</tt>, but it's <tt>cache_method</tt>!
3
+ It's like `alias_method`, but it's `cache_method`!
4
4
 
5
5
  Lets you cache the results of calling methods given their arguments. Like memoization, but stored in Memcached, Redis, etc. so that the cached results can be shared between processes and hosts.
6
6
 
7
- == Real-world usage
7
+ ## Real-world usage
8
8
 
9
- In production use at {impact.brighterplanet.com}[http://impact.brighterplanet.com] and {data.brighterplanet.com}[http://data.brighterplanet.com].
9
+ In production use at [impact.brighterplanet.com](http://impact.brighterplanet.com) and [data.brighterplanet.com](http://data.brighterplanet.com).
10
10
 
11
- == Example
11
+ ## Example
12
12
 
13
13
  require 'cache_method'
14
14
  class Blog
@@ -25,12 +25,11 @@ In production use at {impact.brighterplanet.com}[http://impact.brighterplanet.co
25
25
  end
26
26
  cache_method :get_latest_entries
27
27
 
28
- # cache_method defaults to using the #hash method
29
- # It's a "hash code" (integer! always integer!) representing the internal state of an instance.
30
- # If you need to customize it, you can define #method_cache_hash.
31
- # In that case, it's recommended that you construct a String or a Hash and then call #hash on it (because you should return an integer)
32
- def method_cache_hash
33
- { :name => name, :url => url }.hash
28
+ # By default, cache_method derives the cache key for an instance by getting the SHA1 hash of the Marshal.dump
29
+ # If you need to customize how an instance is recognized, you can define #as_cache_key.
30
+ # Marshal.load will be called on the result.
31
+ def as_cache_key
32
+ { :name => name, :url => url }
34
33
  end
35
34
  end
36
35
 
@@ -41,11 +40,11 @@ Then you can do
41
40
 
42
41
  And clear them too
43
42
 
44
- my_blog.clear_method_cache :get_latest_entries
43
+ my_blog.cache_method_clear :get_latest_entries
45
44
 
46
45
  (which doesn't delete the rest of your cache)
47
46
 
48
- == Configuration (and supported cache clients)
47
+ ## Configuration (and supported cache clients)
49
48
 
50
49
  You need to set where the cache will be stored:
51
50
 
@@ -59,9 +58,9 @@ or this might even work...
59
58
 
60
59
  CacheMethod.config.storage = Rails.cache
61
60
 
62
- See <tt>Config</tt> for the full list of supported caches.
61
+ See `Config` for the full list of supported caches.
63
62
 
64
- == Defining a #hash method (not the same as #to_hash)
63
+ == Defining a #as_cache_key method
65
64
 
66
65
  Since we're not pure functional programmers, sometimes cache hits depend on object state in addition to method arguments. To illustrate:
67
66
 
@@ -71,25 +70,17 @@ get_latest_entries doesn't take any arguments, so it must depend on my_blog.url
71
70
 
72
71
  class Blog
73
72
  # [...]
74
- def method_cache_hash
75
- { :name => name, :url => url }.hash
73
+ def as_cache_key
74
+ { :name => name, :url => url }
76
75
  end
77
76
  # [...]
78
77
  end
79
78
 
80
- You should follow Ruby convention and have <tt>#hash</tt> return a <tt>Fixnum</tt>.
79
+ If you don't define `#as_cache_key`, then `cache_method` will `Marshal.dump` an instance.
81
80
 
82
- Ideally, you should try to make a <tt>String</tt> or a <tt>Hash</tt> and call the standard <tt>#hash</tt> on that.
81
+ ## Module methods
83
82
 
84
- Note: this is NOT the same thing as <tt>#to_hash</tt>! That returns a <b><tt>Hash</tt></b>. What we want is an integer "hash code."
85
-
86
- == Using #method_cache_hash instead of #hash
87
-
88
- If you don't want to modify #hash, use #method_cache_hash instead.
89
-
90
- == Module methods
91
-
92
- You can put <tt>#cache_method</tt> right into your module declarations:
83
+ You can put `#cache_method` right into your module declarations:
93
84
 
94
85
  module MyModule
95
86
  def my_module_method(args)
@@ -106,7 +97,7 @@ You can put <tt>#cache_method</tt> right into your module declarations:
106
97
  extend MyModule
107
98
  end
108
99
 
109
- Rest assured that <tt>Tiger.my_module_method</tt> and <tt>Lion.my_module_method</tt> will be cached correctly and separately. This, on the other hand, won't work:
100
+ Rest assured that `Tiger.my_module_method` and `Lion.my_module_method` will be cached correctly and separately. This, on the other hand, won't work:
110
101
 
111
102
  class Tiger
112
103
  extend MyModule
@@ -114,13 +105,13 @@ Rest assured that <tt>Tiger.my_module_method</tt> and <tt>Lion.my_module_method<
114
105
  # cache_method :my_module_method
115
106
  end
116
107
 
117
- == Rationale
108
+ ## Rationale
118
109
 
119
- * It should be easy to cache a method using memcached, dalli (if you're on heroku), redis, etc. (that's why I made the {cache gem}[https://rubygems.org/gems/cache])
110
+ * It should be easy to cache a method using memcached, dalli (if you're on heroku), redis, etc. (that's why I made the [cache gem](https://rubygems.org/gems/cache))
120
111
  * It should be easy to uncache a method without clearing the whole cache
121
112
  * It should be easy to cache instance methods
122
- * It should be easy to cache methods that depend on object state
113
+ * It should be easy to cache methods that depend on object state (hence `#as_cache_key`)
123
114
 
124
- == Copyright
115
+ ## Copyright
125
116
 
126
- Copyright 2011 Seamus Abshere
117
+ Copyright 2012 Seamus Abshere
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
- require 'bundler'
2
- Bundler::GemHelper.install_tasks
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
3
 
4
4
  require 'rake'
5
5
  require 'rake/testtask'
@@ -11,12 +11,5 @@ end
11
11
 
12
12
  task :default => :test
13
13
 
14
- require 'rake/rdoctask'
15
- Rake::RDocTask.new do |rdoc|
16
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
17
-
18
- rdoc.rdoc_dir = 'rdoc'
19
- rdoc.title = "cache_method #{version}"
20
- rdoc.rdoc_files.include('README*')
21
- rdoc.rdoc_files.include('lib/**/*.rb')
22
- end
14
+ require 'yard'
15
+ YARD::Rake::YardocTask.new
data/cache_method.gemspec CHANGED
@@ -5,7 +5,6 @@ require "cache_method/version"
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "cache_method"
7
7
  s.version = CacheMethod::VERSION
8
- s.platform = Gem::Platform::RUBY
9
8
  s.authors = ["Seamus Abshere"]
10
9
  s.email = ["seamus@abshere.net"]
11
10
  s.homepage = "https://github.com/seamusabshere/cache_method"
@@ -19,11 +18,4 @@ Gem::Specification.new do |s|
19
18
  s.require_paths = ["lib"]
20
19
 
21
20
  s.add_dependency 'cache', '>=0.2.1'
22
- s.add_development_dependency 'memcached'
23
- s.add_development_dependency 'rake'
24
- # if RUBY_VERSION >= '1.9'
25
- # s.add_development_dependency 'ruby-debug19'
26
- # else
27
- # s.add_development_dependency 'ruby-debug'
28
- # end
29
21
  end
@@ -1,6 +1,8 @@
1
- require 'digest/md5'
1
+ require 'digest/sha1'
2
2
  module CacheMethod
3
3
  class CachedResult #:nodoc: all
4
+ CACHE_KEY_JOINER = ','
5
+
4
6
  def initialize(obj, method_id, original_method_id, ttl, args)
5
7
  @obj = obj
6
8
  @method_id = method_id
@@ -17,7 +19,7 @@ module CacheMethod
17
19
  # Store things wrapped in an Array so that nil is accepted
18
20
  def fetch
19
21
  if v = Config.instance.storage.get(cache_key) and v.is_a?(::Array)
20
- v[0]
22
+ v.first
21
23
  else
22
24
  v = obj.send original_method_id, *args
23
25
  Config.instance.storage.set cache_key, [v], ttl
@@ -31,9 +33,9 @@ module CacheMethod
31
33
 
32
34
  def cache_key
33
35
  if obj.is_a?(::Class) or obj.is_a?(::Module)
34
- [ 'CacheMethod', 'CachedResult', method_signature, current_generation, args_digest ].compact.join ','
36
+ [ 'CacheMethod', 'CachedResult', method_signature, current_generation, args_digest ].compact.join CACHE_KEY_JOINER
35
37
  else
36
- [ 'CacheMethod', 'CachedResult', method_signature, obj_hash, current_generation, args_digest ].compact.join ','
38
+ [ 'CacheMethod', 'CachedResult', method_signature, obj_digest, current_generation, args_digest ].compact.join CACHE_KEY_JOINER
37
39
  end
38
40
  end
39
41
 
@@ -41,12 +43,12 @@ module CacheMethod
41
43
  @method_signature ||= ::CacheMethod.method_signature(obj, method_id)
42
44
  end
43
45
 
44
- def obj_hash
45
- @obj_hash ||= obj.respond_to?(:method_cache_hash) ? obj.method_cache_hash : obj.hash
46
+ def obj_digest
47
+ @obj_digest ||= ::Digest::SHA1.hexdigest(::Marshal.dump(obj.respond_to?(:as_cache_key) ? obj.as_cache_key : obj))
46
48
  end
47
49
 
48
50
  def args_digest
49
- @args_digest ||= args.empty? ? 'empty' : ::Digest::MD5.hexdigest(args.join)
51
+ @args_digest ||= args.empty? ? 'empty' : ::Digest::SHA1.hexdigest(::Marshal.dump(args))
50
52
  end
51
53
 
52
54
  def current_generation
@@ -54,5 +56,9 @@ module CacheMethod
54
56
  @current_generation ||= Generation.new(obj, method_id).current
55
57
  end
56
58
  end
59
+
60
+ def arity
61
+ @arity ||= obj.method(original_method_id).arity
62
+ end
57
63
  end
58
64
  end
@@ -1,3 +1,4 @@
1
+ require 'digest/sha1'
1
2
  module CacheMethod
2
3
  class Generation #:nodoc: all
3
4
  class << self
@@ -18,15 +19,15 @@ module CacheMethod
18
19
  @method_signature ||= ::CacheMethod.method_signature(obj, method_id)
19
20
  end
20
21
 
21
- def obj_hash
22
- @obj_hash ||= obj.respond_to?(:method_cache_hash) ? obj.method_cache_hash : obj.hash
22
+ def obj_digest
23
+ @obj_digest ||= ::Digest::SHA1.hexdigest(::Marshal.dump(obj.respond_to?(:as_cache_key) ? obj.as_cache_key : obj))
23
24
  end
24
25
 
25
26
  def cache_key
26
- if obj.is_a? ::Class or obj.is_a? ::Module
27
+ if obj.is_a?(::Class) or obj.is_a?(::Module)
27
28
  [ 'CacheMethod', 'Generation', method_signature ].join ','
28
29
  else
29
- [ 'CacheMethod', 'Generation', method_signature, obj_hash ].join ','
30
+ [ 'CacheMethod', 'Generation', method_signature, obj_digest ].join ','
30
31
  end
31
32
  end
32
33
 
@@ -1,3 +1,3 @@
1
1
  module CacheMethod
2
- VERSION = "0.1.6"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/cache_method.rb CHANGED
@@ -1,10 +1,9 @@
1
- require 'cache_method/version'
1
+ require 'cache_method/config'
2
+ require 'cache_method/cached_result'
3
+ require 'cache_method/generation'
4
+
2
5
  # See the README.rdoc for more info!
3
6
  module CacheMethod
4
- autoload :Config, 'cache_method/config'
5
- autoload :CachedResult, 'cache_method/cached_result'
6
- autoload :Generation, 'cache_method/generation'
7
-
8
7
  def self.config #:nodoc:
9
8
  Config.instance
10
9
  end
@@ -21,19 +20,19 @@ module CacheMethod
21
20
  [ klass_name(obj), method_id ].join method_delimiter(obj)
22
21
  end
23
22
 
24
- # All Objects, including instances and Classes, get the <tt>#clear_method_cache</tt> method.
23
+ # All Objects, including instances and Classes, get the <tt>#cache_method_clear</tt> method.
25
24
  module InstanceMethods
26
25
  # Clear the cache for a particular method.
27
26
  #
28
- # Note: Remember to define <tt>#hash</tt> on any object whose instance methods might get cached.
27
+ # Note: Remember to define <tt>#as_cache_key</tt> on any object whose instance methods might get cached.
29
28
  #
30
29
  # Example:
31
- # my_blog.clear_method_cache :get_latest_entries
32
- def clear_method_cache(method_id)
30
+ # my_blog.cache_method_clear :get_latest_entries
31
+ def cache_method_clear(method_id)
33
32
  if ::CacheMethod.config.generational?
34
33
  ::CacheMethod::Generation.new(self, method_id).mark_passing
35
34
  else
36
- raise ::RuntimeError, "[cache_method] clear_method_cache called, but you have disabled generational caching. Check your setting for CacheMethod.config.generational"
35
+ raise ::RuntimeError, "[cache_method] cache_method_clear called, but you have disabled generational caching. Check your setting for CacheMethod.config.generational"
37
36
  end
38
37
  end
39
38
  end
@@ -42,7 +41,7 @@ module CacheMethod
42
41
  module ClassMethods
43
42
  # Cache a method. TTL in seconds, defaults to whatever's in CacheMethod.config.default_ttl
44
43
  #
45
- # Note: Remember to define <tt>#hash</tt> on any object whose instance methods might get cached.
44
+ # Note: Remember to define <tt>#as_cache_key</tt> on any object whose instance methods might get cached.
46
45
  #
47
46
  # Note 2: Check out CacheMethod.config.default_ttl... the default is 24 hours.
48
47
  #
data/test/helper.rb CHANGED
@@ -25,30 +25,20 @@ class CopyCat1
25
25
  # representation."
26
26
  def echo(*args)
27
27
  self.echo_count += 1
28
- if RUBY_VERSION >= '1.9'
29
- if args.empty?
30
- return nil
31
- elsif args.length == 1
32
- return args[0]
33
- else
34
- return args
35
- end
36
- else
37
- return *args
38
- end
28
+ return *args
39
29
  end
40
- def hash
41
- raise "Used hash"
30
+ def marshal_dump
31
+ raise "Used marshal_dump"
42
32
  end
43
- def method_cache_hash
44
- name.hash
33
+ def as_cache_key
34
+ name
45
35
  end
46
36
  cache_method :echo
47
37
  end
48
38
 
49
39
  class CopyCat1a < CopyCat1
50
- def method_cache_hash
51
- raise "Used method_cache_hash"
40
+ def as_cache_key
41
+ raise "Used as_cache_key"
52
42
  end
53
43
  end
54
44
 
@@ -113,8 +103,8 @@ class Blog1
113
103
  ["voo vaa #{name}"]
114
104
  end
115
105
  cache_method :get_latest_entries2, 1 # second
116
- def hash
117
- { :name => name, :url => url }.hash
106
+ def as_cache_key
107
+ { :name => name, :url => url }
118
108
  end
119
109
  end
120
110
  def new_instance_of_my_blog
@@ -158,3 +148,9 @@ CopyCat1.extend Say
158
148
  CopyCat2.extend Say
159
149
 
160
150
  CopyCat1.send :include, Say
151
+
152
+ class DontStringifyMe < Struct.new(:message)
153
+ def to_s
154
+ "Don't stringify me, read my message!"
155
+ end
156
+ end
@@ -1,6 +1,6 @@
1
1
  require 'helper'
2
2
 
3
- require 'memcached'
3
+ require 'dalli'
4
4
 
5
5
  class TestCacheMethod < Test::Unit::TestCase
6
6
  def setup
@@ -8,114 +8,178 @@ class TestCacheMethod < Test::Unit::TestCase
8
8
  CopyCat2.echo_count = 0
9
9
  CopyCat1.say_count = 0
10
10
  CopyCat2.say_count = 0
11
- my_cache = Memcached.new '127.0.0.1:11211', :binary => true
11
+ my_cache = Dalli::Client.new '127.0.0.1:11211'
12
12
  my_cache.flush
13
13
  CacheMethod.config.storage = my_cache
14
14
  CacheMethod.config.generational = true
15
15
  end
16
-
16
+
17
17
  def test_cache_instance_method_with_args
18
18
  a = CopyCat1.new 'mimo'
19
-
20
- assert_equal 'hi', a.echo('hi')
21
- assert_equal 1, a.echo_count
22
-
23
- assert_equal 'hi', a.echo('hi')
24
- assert_equal 1, a.echo_count
19
+
20
+ if RUBY_VERSION >= '1.9'
21
+ assert_equal ['hi'], a.echo('hi')
22
+ assert_equal 1, a.echo_count
23
+
24
+ assert_equal ['hi'], a.echo('hi')
25
+ assert_equal 1, a.echo_count
26
+ else
27
+ assert_equal 'hi', a.echo('hi')
28
+ assert_equal 1, a.echo_count
29
+
30
+ assert_equal 'hi', a.echo('hi')
31
+ assert_equal 1, a.echo_count
32
+ end
25
33
  end
26
-
34
+
27
35
  def test_cache_instance_method_with_nil_args
28
36
  a = CopyCat1.new 'mimo'
29
- assert_equal nil, a.echo
30
- assert_equal 1, a.echo_count
31
-
32
- assert_equal nil, a.echo
33
- assert_equal 1, a.echo_count
34
-
35
- assert_equal nil, a.echo(nil)
36
- assert_equal 2, a.echo_count
37
-
38
- assert_equal nil, a.echo(nil)
39
- assert_equal 2, a.echo_count
37
+
38
+ if RUBY_VERSION >= '1.9'
39
+ assert_equal [], a.echo
40
+ assert_equal 1, a.echo_count
41
+
42
+ assert_equal [], a.echo
43
+ assert_equal 1, a.echo_count
44
+
45
+ assert_equal [nil], a.echo(nil)
46
+ assert_equal 2, a.echo_count
47
+
48
+ assert_equal [nil], a.echo(nil)
49
+ assert_equal 2, a.echo_count
50
+ else
51
+ assert_equal nil, a.echo
52
+ assert_equal 1, a.echo_count
53
+
54
+ assert_equal nil, a.echo
55
+ assert_equal 1, a.echo_count
56
+
57
+ assert_equal nil, a.echo(nil)
58
+ assert_equal 2, a.echo_count
59
+
60
+ assert_equal nil, a.echo(nil)
61
+ assert_equal 2, a.echo_count
62
+ end
40
63
  end
41
-
64
+
42
65
  def test_cache_instance_method_with_array_args
43
66
  a = CopyCat1.new 'mimo'
44
-
45
- assert_equal ['hi'], a.echo(['hi'])
46
- assert_equal 1, a.echo_count
47
-
48
- assert_equal ['hi'], a.echo(['hi'])
49
- assert_equal 1, a.echo_count
50
-
51
- assert_equal ['bye'], a.echo(['bye'])
52
- assert_equal 2, a.echo_count
53
-
54
- assert_equal ['bye'], a.echo(['bye'])
55
- assert_equal 2, a.echo_count
56
-
57
- assert_equal ['hi', 'there'], a.echo(['hi', 'there'])
58
- assert_equal 3, a.echo_count
59
-
60
- # same as previous
61
- assert_equal ['hi', 'there'], a.echo('hi', 'there')
62
- assert_equal 3, a.echo_count
63
-
64
- assert_equal [], a.echo([])
65
- assert_equal 4, a.echo_count
66
-
67
- assert_equal [], a.echo([])
68
- assert_equal 4, a.echo_count
67
+
68
+ if RUBY_VERSION >= '1.9'
69
+ assert_equal [['hi']], a.echo(['hi'])
70
+ assert_equal 1, a.echo_count
71
+
72
+ assert_equal [['hi']], a.echo(['hi'])
73
+ assert_equal 1, a.echo_count
74
+
75
+ assert_equal [['bye']], a.echo(['bye'])
76
+ assert_equal 2, a.echo_count
77
+
78
+ assert_equal [['bye']], a.echo(['bye'])
79
+ assert_equal 2, a.echo_count
80
+
81
+ assert_equal [[]], a.echo([])
82
+ assert_equal 3, a.echo_count
83
+
84
+ assert_equal [[]], a.echo([])
85
+ assert_equal 3, a.echo_count
86
+ else
87
+ assert_equal ['hi'], a.echo(['hi'])
88
+ assert_equal 1, a.echo_count
89
+
90
+ assert_equal ['hi'], a.echo(['hi'])
91
+ assert_equal 1, a.echo_count
92
+
93
+ assert_equal ['bye'], a.echo(['bye'])
94
+ assert_equal 2, a.echo_count
95
+
96
+ assert_equal ['bye'], a.echo(['bye'])
97
+ assert_equal 2, a.echo_count
98
+
99
+ assert_equal [], a.echo([])
100
+ assert_equal 3, a.echo_count
101
+
102
+ assert_equal [], a.echo([])
103
+ assert_equal 3, a.echo_count
104
+ end
69
105
  end
70
-
106
+
107
+ def test_cache_instance_method_with_array_args_splat
108
+ a = CopyCat1.new 'mimo'
109
+
110
+ if RUBY_VERSION >= '1.9'
111
+ assert_equal [['hi', 'there']], a.echo(['hi', 'there'])
112
+ assert_equal 1, a.echo_count
113
+
114
+ assert_equal ['hi', 'there'], a.echo('hi', 'there')
115
+ assert_equal 2, a.echo_count
116
+ else
117
+ assert_equal ['hi', 'there'], a.echo(['hi', 'there'])
118
+ assert_equal 1, a.echo_count
119
+
120
+ assert_equal ['hi', 'there'], a.echo('hi', 'there')
121
+ assert_equal 2, a.echo_count
122
+ end
123
+ end
124
+
71
125
  def test_cache_class_method_with_args
72
126
  assert_equal 'hi', CopyCat2.echo('hi')
73
127
  assert_equal 1, CopyCat2.echo_count
74
-
128
+
75
129
  assert_equal 'hi', CopyCat2.echo('hi')
76
130
  assert_equal 1, CopyCat2.echo_count
77
131
  end
78
-
132
+
79
133
  def test_cache_class_method_with_nil_args
80
134
  assert_equal nil, CopyCat2.echo
81
135
  assert_equal 1, CopyCat2.echo_count
82
-
136
+
83
137
  assert_equal nil, CopyCat2.echo
84
138
  assert_equal 1, CopyCat2.echo_count
85
-
139
+
86
140
  assert_equal nil, CopyCat2.echo(nil)
87
141
  assert_equal 2, CopyCat2.echo_count
88
-
142
+
89
143
  assert_equal nil, CopyCat2.echo(nil)
90
- assert_equal 2, CopyCat2.echo_count
144
+ assert_equal 2, CopyCat2.echo_count
91
145
  end
92
-
146
+
93
147
  def test_cache_class_method_with_array_args
94
148
  assert_equal ['hi'], CopyCat2.echo(['hi'])
95
149
  assert_equal 1, CopyCat2.echo_count
96
-
150
+
97
151
  assert_equal ['hi'], CopyCat2.echo(['hi'])
98
152
  assert_equal 1, CopyCat2.echo_count
99
-
153
+
100
154
  assert_equal ['bye'], CopyCat2.echo(['bye'])
101
155
  assert_equal 2, CopyCat2.echo_count
102
-
156
+
103
157
  assert_equal ['bye'], CopyCat2.echo(['bye'])
104
158
  assert_equal 2, CopyCat2.echo_count
105
-
106
- assert_equal ['hi', 'there'], CopyCat2.echo(['hi', 'there'])
107
- assert_equal 3, CopyCat2.echo_count
108
-
109
- assert_equal ['hi', 'there'], CopyCat2.echo('hi', 'there')
110
- assert_equal 3, CopyCat2.echo_count
111
-
159
+
112
160
  assert_equal [], CopyCat2.echo([])
113
- assert_equal 4, CopyCat2.echo_count
114
-
161
+ assert_equal 3, CopyCat2.echo_count
162
+
115
163
  assert_equal [], CopyCat2.echo([])
116
- assert_equal 4, CopyCat2.echo_count
164
+ assert_equal 3, CopyCat2.echo_count
165
+ end
166
+
167
+ def test_cache_class_method_with_array_args_splat
168
+ if RUBY_VERSION >= '1.9'
169
+ assert_equal ['hi', 'there'], CopyCat2.echo(['hi', 'there'])
170
+ assert_equal 1, CopyCat2.echo_count
171
+
172
+ assert_equal ['hi', 'there'], CopyCat2.echo('hi', 'there')
173
+ assert_equal 2, CopyCat2.echo_count
174
+ else
175
+ assert_equal ['hi', 'there'], CopyCat2.echo(['hi', 'there'])
176
+ assert_equal 1, CopyCat2.echo_count
177
+
178
+ assert_equal ['hi', 'there'], CopyCat2.echo('hi', 'there')
179
+ assert_equal 2, CopyCat2.echo_count
180
+ end
117
181
  end
118
-
182
+
119
183
  def test_cache_instance_method
120
184
  a = new_instance_of_my_blog
121
185
  assert_equal ["hello from #{a.name}"], a.get_latest_entries
@@ -127,25 +191,25 @@ class TestCacheMethod < Test::Unit::TestCase
127
191
  assert_equal ["hello from #{xxx.name}"], xxx.get_latest_entries
128
192
  assert_equal 1, xxx.request_count
129
193
  end
130
-
194
+
131
195
  def test_clear_instance_method
132
196
  a = new_instance_of_my_blog
133
197
  assert_equal ["hello from #{a.name}"], a.get_latest_entries
134
198
  assert_equal 1, a.request_count
135
- a.clear_method_cache :get_latest_entries
199
+ a.cache_method_clear :get_latest_entries
136
200
  assert_equal ["hello from #{a.name}"], a.get_latest_entries
137
201
  assert_equal 2, a.request_count
138
202
  end
139
-
203
+
140
204
  def test_clear_correct_instance_method
141
205
  a = new_instance_of_my_blog
142
206
  assert_equal ["hello from #{a.name}"], a.get_latest_entries
143
207
  assert_equal 1, a.request_count
144
- a.clear_method_cache :foobar
208
+ a.cache_method_clear :foobar
145
209
  assert_equal ["hello from #{a.name}"], a.get_latest_entries
146
210
  assert_equal 1, a.request_count
147
211
  end
148
-
212
+
149
213
  def test_clear_instance_method_from_correct_instance
150
214
  a = new_instance_of_my_blog
151
215
  assert_equal ["hello from #{a.name}"], a.get_latest_entries
@@ -153,13 +217,13 @@ class TestCacheMethod < Test::Unit::TestCase
153
217
  xxx = new_instance_of_another_blog
154
218
  assert_equal ["hello from #{xxx.name}"], xxx.get_latest_entries
155
219
  assert_equal 1, xxx.request_count
156
- xxx.clear_method_cache :get_latest_entries
220
+ xxx.cache_method_clear :get_latest_entries
157
221
  assert_equal ["hello from #{a.name}"], a.get_latest_entries
158
222
  assert_equal 1, a.request_count
159
223
  assert_equal ["hello from #{xxx.name}"], xxx.get_latest_entries
160
224
  assert_equal 2, xxx.request_count
161
225
  end
162
-
226
+
163
227
  def test_cache_instance_method_ttl
164
228
  a = new_instance_of_my_blog
165
229
  assert_equal ["voo vaa #{a.name}"], a.get_latest_entries2
@@ -168,7 +232,7 @@ class TestCacheMethod < Test::Unit::TestCase
168
232
  assert_equal ["voo vaa #{a.name}"], a.get_latest_entries2
169
233
  assert_equal 2, a.request_count
170
234
  end
171
-
235
+
172
236
  def test_cache_class_method
173
237
  assert_equal 0, Blog2.request_count
174
238
  assert_equal 'danke schoen', Blog2.get_latest_entries
@@ -176,52 +240,68 @@ class TestCacheMethod < Test::Unit::TestCase
176
240
  assert_equal 'danke schoen', Blog2.get_latest_entries
177
241
  assert_equal 1, Blog2.request_count
178
242
  end
179
-
243
+
180
244
  def test_clear_class_method
181
245
  assert_equal 0, Blog2.request_count
182
246
  assert_equal 'danke schoen', Blog2.get_latest_entries
183
247
  assert_equal 1, Blog2.request_count
184
- Blog2.clear_method_cache :get_latest_entries
248
+ Blog2.cache_method_clear :get_latest_entries
185
249
  assert_equal 'danke schoen', Blog2.get_latest_entries
186
250
  assert_equal 2, Blog2.request_count
187
251
  end
188
-
252
+
189
253
  def test_clear_correct_class_method
190
254
  assert_equal 0, Blog2.request_count
191
255
  assert_equal 'danke schoen', Blog2.get_latest_entries
192
256
  assert_equal 1, Blog2.request_count
193
-
194
- Blog2.clear_method_cache :foobar
257
+
258
+ Blog2.cache_method_clear :foobar
195
259
  assert_equal 'danke schoen', Blog2.get_latest_entries
196
260
  assert_equal 1, Blog2.request_count
197
-
198
- Blog2.clear_method_cache :get_latest_entries
261
+
262
+ Blog2.cache_method_clear :get_latest_entries
199
263
  assert_equal 'danke schoen', Blog2.get_latest_entries
200
264
  assert_equal 2, Blog2.request_count
201
265
  end
202
-
266
+
203
267
  def test_never_set_storage
204
268
  CacheMethod.config.instance_variable_set :@storage, nil
205
269
  a = CopyCat1.new 'mimo'
206
-
207
- assert_equal 'hi', a.echo('hi')
208
- assert_equal 1, a.echo_count
209
-
210
- assert_equal 'hi', a.echo('hi')
211
- assert_equal 1, a.echo_count
270
+
271
+ if RUBY_VERSION >= '1.9'
272
+ assert_equal ['hi'], a.echo('hi')
273
+ assert_equal 1, a.echo_count
274
+
275
+ assert_equal ['hi'], a.echo('hi')
276
+ assert_equal 1, a.echo_count
277
+ else
278
+ assert_equal 'hi', a.echo('hi')
279
+ assert_equal 1, a.echo_count
280
+
281
+ assert_equal 'hi', a.echo('hi')
282
+ assert_equal 1, a.echo_count
283
+ end
212
284
  end
213
-
285
+
214
286
  def test_set_storage_to_nil
215
287
  CacheMethod.config.storage = nil
216
288
  a = CopyCat1.new 'mimo'
217
-
218
- assert_equal 'hi', a.echo('hi')
219
- assert_equal 1, a.echo_count
220
-
221
- assert_equal 'hi', a.echo('hi')
222
- assert_equal 1, a.echo_count
289
+
290
+ if RUBY_VERSION >= '1.9'
291
+ assert_equal ['hi'], a.echo('hi')
292
+ assert_equal 1, a.echo_count
293
+
294
+ assert_equal ['hi'], a.echo('hi')
295
+ assert_equal 1, a.echo_count
296
+ else
297
+ assert_equal 'hi', a.echo('hi')
298
+ assert_equal 1, a.echo_count
299
+
300
+ assert_equal 'hi', a.echo('hi')
301
+ assert_equal 1, a.echo_count
302
+ end
223
303
  end
224
-
304
+
225
305
  def test_cache_module_method
226
306
  assert_equal 0, BlogM.request_count
227
307
  assert_equal 'danke schoen', BlogM.get_latest_entries
@@ -229,14 +309,14 @@ class TestCacheMethod < Test::Unit::TestCase
229
309
  assert_equal 'danke schoen', BlogM.get_latest_entries
230
310
  assert_equal 1, BlogM.request_count
231
311
  end
232
-
233
- def test_method_cache_hash
234
- assert_raises(RuntimeError, /Used method_cache_hash/) do
312
+
313
+ def test_as_cache_key
314
+ assert_raises(RuntimeError, /Used as_cache_key/) do
235
315
  a = CopyCat1a.new 'mimo'
236
316
  a.echo 'hi'
237
317
  end
238
318
  end
239
-
319
+
240
320
  def test_method_added_by_extension
241
321
  assert_equal 'hi', CopyCat2.say('hi')
242
322
  assert_equal 1, CopyCat2.say_count
@@ -244,17 +324,17 @@ class TestCacheMethod < Test::Unit::TestCase
244
324
  assert_equal 'hi', CopyCat2.say('hi')
245
325
  assert_equal 1, CopyCat2.say_count
246
326
  end
247
-
327
+
248
328
  def test_method_added_by_inclusion
249
329
  a = CopyCat1.new 'sayer'
250
330
 
251
331
  assert_equal 'hi', a.say('hi')
252
332
  assert_equal 1, a.say_count
253
-
333
+
254
334
  assert_equal 'hi', a.say('hi')
255
335
  assert_equal 1, a.say_count
256
336
  end
257
-
337
+
258
338
  def test_not_confused_by_module
259
339
  assert_equal 'hi', CopyCat2.say('hi')
260
340
  assert_equal 1, CopyCat2.say_count
@@ -268,31 +348,58 @@ class TestCacheMethod < Test::Unit::TestCase
268
348
  assert_equal 'hi', CopyCat1.say('hi')
269
349
  assert_equal 1, CopyCat1.say_count
270
350
  end
271
-
351
+
272
352
  def test_disable_generational_caching
273
353
  CacheMethod.config.generational = false
274
-
354
+
275
355
  a = CopyCat1.new 'mimo'
276
-
277
- assert_equal 'hi', a.echo('hi')
278
- assert_equal 1, a.echo_count
279
-
280
- assert_equal 'hi', a.echo('hi')
281
- assert_equal 1, a.echo_count
356
+
357
+ if RUBY_VERSION >= '1.9'
358
+ assert_equal ['hi'], a.echo('hi')
359
+ assert_equal 1, a.echo_count
360
+
361
+ assert_equal ['hi'], a.echo('hi')
362
+ assert_equal 1, a.echo_count
363
+ else
364
+ assert_equal 'hi', a.echo('hi')
365
+ assert_equal 1, a.echo_count
366
+
367
+ assert_equal 'hi', a.echo('hi')
368
+ assert_equal 1, a.echo_count
369
+ end
282
370
  end
283
-
284
- def test_cant_clear_method_cache_without_generational_caching
371
+
372
+ def test_cant_cache_method_clear_without_generational_caching
285
373
  CacheMethod.config.generational = false
286
374
 
287
375
  a = new_instance_of_my_blog
288
376
  assert_equal ["hello from #{a.name}"], a.get_latest_entries
289
377
  assert_equal 1, a.request_count
290
-
378
+
291
379
  assert_raises(::RuntimeError) do
292
- a.clear_method_cache :get_latest_entries
380
+ a.cache_method_clear :get_latest_entries
293
381
  end
294
-
382
+
295
383
  assert_equal ["hello from #{a.name}"], a.get_latest_entries
296
384
  assert_equal 1, a.request_count
297
385
  end
386
+
387
+ def test_doesnt_rely_on_to_s_for_args_digest
388
+ hello = DontStringifyMe.new("hello")
389
+ world = DontStringifyMe.new("world")
390
+
391
+ a = CopyCat1.new 'mimo'
392
+
393
+ a.echo(hello)
394
+ assert_equal 1, a.echo_count
395
+
396
+ a.echo(hello)
397
+ assert_equal 1, a.echo_count
398
+
399
+ a.echo(world)
400
+ assert_equal 2, a.echo_count
401
+
402
+ a.echo(world)
403
+ assert_equal 2, a.echo_count
404
+ end
298
405
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cache_method
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-17 00:00:00.000000000Z
12
+ date: 2012-03-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cache
16
- requirement: &2155074680 !ruby/object:Gem::Requirement
16
+ requirement: &2156275580 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,29 +21,7 @@ dependencies:
21
21
  version: 0.2.1
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2155074680
25
- - !ruby/object:Gem::Dependency
26
- name: memcached
27
- requirement: &2155073740 !ruby/object:Gem::Requirement
28
- none: false
29
- requirements:
30
- - - ! '>='
31
- - !ruby/object:Gem::Version
32
- version: '0'
33
- type: :development
34
- prerelease: false
35
- version_requirements: *2155073740
36
- - !ruby/object:Gem::Dependency
37
- name: rake
38
- requirement: &2155072900 !ruby/object:Gem::Requirement
39
- none: false
40
- requirements:
41
- - - ! '>='
42
- - !ruby/object:Gem::Version
43
- version: '0'
44
- type: :development
45
- prerelease: false
46
- version_requirements: *2155072900
24
+ version_requirements: *2156275580
47
25
  description: Like alias_method, but it's cache_method!
48
26
  email:
49
27
  - seamus@abshere.net
@@ -52,8 +30,9 @@ extensions: []
52
30
  extra_rdoc_files: []
53
31
  files:
54
32
  - .gitignore
33
+ - CHANGELOG
55
34
  - Gemfile
56
- - README.rdoc
35
+ - README.markdown
57
36
  - Rakefile
58
37
  - cache_method.gemspec
59
38
  - lib/cache_method.rb
@@ -83,7 +62,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
62
  version: '0'
84
63
  requirements: []
85
64
  rubyforge_project: cache_method
86
- rubygems_version: 1.8.11
65
+ rubygems_version: 1.8.15
87
66
  signing_key:
88
67
  specification_version: 3
89
68
  summary: Lets you cache methods (to memcached, redis, etc.) sort of like you can memoize
@@ -91,3 +70,4 @@ summary: Lets you cache methods (to memcached, redis, etc.) sort of like you can
91
70
  test_files:
92
71
  - test/helper.rb
93
72
  - test/test_cache_method.rb
73
+ has_rdoc: