cachely 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ gemspec
5
5
 
6
6
  group :test do
7
7
  gem 'pg'
8
- gem 'activerecord', :require => "active_record"
8
+ gem 'activerecord', "~> 3.2.12", :require => "active_record"
9
9
  gem 'activesupport'
10
10
  gem 'test-unit'
11
11
  gem 'cucumber'
data/README.md CHANGED
@@ -1,7 +1,81 @@
1
1
  # Cachely
2
2
 
3
- TODO: Write a gem description
3
+ Transparent method level caching using redis. Event machine optional.
4
4
 
5
+ ## Usage
6
+
7
+ class A
8
+ include Cachely
9
+
10
+ cachely :foo
11
+
12
+ def foo
13
+ sleep(10)
14
+ return rand(500) #Holy moly, what a HUGE, LONG CALL! Returns a different value every time.
15
+ end
16
+
17
+ end
18
+
19
+ a = A.new
20
+
21
+ start = Time.now
22
+ result_1 = a.foo
23
+ after = Time.now
24
+ time_1 = after-start
25
+
26
+ start = Time.now
27
+ result_2 = a.foo #Now it uses the redis cache.
28
+ after = Time.now
29
+ time_2 = after-start
30
+
31
+ p "First call took #{time_1}"
32
+
33
+ p "Second call took #{time_2}"
34
+
35
+ p "Results equal? #{result_2 == result_1}. Of course! It cached the output."
36
+
37
+ => "First call took 10.031092"
38
+ => "Second call took 0.032047"
39
+ => "Results equal? true. Of course! It cached the output."
40
+
41
+
42
+ In order to make this work, you must connect to a redis store using the method:
43
+
44
+ Cachely::Mechanics.connect(opts = {})
45
+
46
+ Opts accepts keys :host, :port, :password, :driver. See redis-rb documentation for which drivers you want,
47
+ including whether or not you wish it to be evented.
48
+
49
+ I'd recommend doing this in a Rails initializer, or if you're using sinatra or other rack app, in config.ru.
50
+
51
+ If you want cached results to expire, instead of
52
+
53
+ cachely :foo
54
+
55
+ use
56
+
57
+ cachely :foo, time_to_expiry: 3.minutes
58
+
59
+ If you have a class method of the same name as an instance variable,
60
+
61
+ cachely :foo
62
+
63
+ will still work, it will cache both the instance method foo and the class method foo, but in different
64
+ keyed locations, of course. To specify instance or class method, do
65
+
66
+ cachely :foo, :type => "instance"
67
+ cachely :foo, :type => "class"
68
+
69
+ Cachely is able to figure out whether or not to use the cache by looking at the arguments you pass in.
70
+ Generally, if your arguments are the same, and the object you're calling the method on is the same(Cachely uses
71
+ the to_json method on the object you call the method on to determine this), then it assumes the result
72
+ will be the same and uses the cached result.
73
+
74
+ CAVEAT: Do NOT use Cachely for functions that depend on time of day or random numbers, as these are inherently uncachable.
75
+ If you check the tests out, you'll see random number functions are used exhaustively to test the caching ability of cachely,
76
+ because we know the function wasn't called if the second call yields the same number.
77
+
78
+ If you do not understand the implications of the caveat, do not use cachely. You're not ready yet.
5
79
  ## Installation
6
80
 
7
81
  Add this line to your application's Gemfile:
@@ -16,10 +90,6 @@ Or install it yourself as:
16
90
 
17
91
  $ gem install cachely
18
92
 
19
- ## Usage
20
-
21
- TODO: Write usage instructions here
22
-
23
93
  ## Contributing
24
94
 
25
95
  1. Fork it
data/cachely.gemspec CHANGED
@@ -4,8 +4,8 @@ require File.expand_path('../lib/cachely/version', __FILE__)
4
4
  Gem::Specification.new do |gem|
5
5
  gem.authors = ["Jordan Prince"]
6
6
  gem.email = ["jordanmprince@gmail.com"]
7
- gem.description = %q{Coming soon.}
8
- gem.summary = %q{Use em-redis to transparently cache results from your class methods. Eventmachine compatible out of the box!}
7
+ gem.description = %q{Transparently cache the results of methods using redis.}
8
+ gem.summary = %q{Transparently cache the results of methods using redis.}
9
9
  gem.homepage = ""
10
10
 
11
11
  gem.files = `git ls-files`.split($\)
@@ -14,5 +14,8 @@ Gem::Specification.new do |gem|
14
14
  gem.name = "cachely"
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Cachely::VERSION
17
- gem.add_dependency "em-hiredis"
17
+ gem.add_dependency "redis", '~> 3.0.1'
18
+ gem.add_dependency "hiredis", '~> 0.4.5'
19
+ gem.add_dependency "em-synchrony"
20
+ gem.add_dependency "json"
18
21
  end
data/config/database.yml CHANGED
@@ -2,5 +2,6 @@ test:
2
2
  adapter: postgresql
3
3
  database: cachely_test
4
4
  host: localhost
5
+ password: pi
5
6
  pool: 60
6
7
 
data/config/redis.yml ADDED
@@ -0,0 +1,4 @@
1
+ test:
2
+ host: 127.0.0.1
3
+ port: 6379
4
+
data/lib/cachely.rb CHANGED
@@ -1,25 +1,55 @@
1
1
  require_relative "cachely/version"
2
-
2
+ require_relative 'cachely/mechanics'
3
+ require 'redis'
4
+ require 'hiredis'
5
+ require 'em-synchrony'
6
+ require 'json'
3
7
  module Cachely
4
8
  module ClassMethods
5
-
9
+
10
+ # Called after class methods loaded, this aliases out the old method, puts in place the listener version
11
+ # That only calls it if the cache can't fill in.
12
+ #
13
+ # @name [Symbol] fcn name
14
+ # @return nil
15
+ def singleton_method_added(name)
16
+ if(@cachely_fcns and @cachely_fcns.include?(name) and !self.respond_to?("#{name.to_s}_old".to_sym))
17
+ unless(@cachely_opts[name][:type] and @cachely_opts[name][:type] == "instance")
18
+ self.instance_eval("alias :#{"#{name.to_s}_old".to_sym} :#{name}")
19
+ Cachely::Mechanics.setup_method(self,name, @cachely_opts[name][:time_to_expiry], true)
20
+ end
21
+ end
22
+ super
23
+ end
24
+
25
+ # Called after methods loaded, this aliases out the old method, puts in place the listener version
26
+ # That only calls it if the cache can't fill in.
27
+ #
28
+ # @name [Symbol] fcn name
29
+ # @return nil
6
30
  def method_added(name)
7
- if(@cachely_fcns.include?(name) and !@cachely_fcns_added.include?(name))
8
- @cachely_fcns_added << name #this method'll get called when we do define method below
9
- #this halts that.
10
-
11
- self.class_eval("alias #{"#{name.to_s}_old".to_sym} #{name}") #alias old function out
12
-
13
- self.define_method name do |*args| #define new one
14
- send "#{name.to_s}_old".to_sym, *args
31
+ if(@cachely_fcns and @cachely_fcns.include?(name) and !self.new.respond_to?("#{name.to_s}_old".to_sym))
32
+ # only do this if we either haven't explicitly labeled fcn type, or it's not class.
33
+ unless(@cachely_opts[name][:type] and @cachely_opts[name][:type] == "class")
34
+ self.class_eval("alias :#{"#{name.to_s}_old".to_sym} :#{name}") #alias old function out
35
+ Cachely::Mechanics.setup_method(self,name, @cachely_opts[name][:time_to_expiry])
15
36
  end
16
37
  end
38
+ super
17
39
  end
18
40
 
41
+ # Catches the method name, stores for after because methods aren't loaded when this is called.
42
+ #
43
+ # @fcn [Symbol] fcn name
44
+ # @opts [Hash] options
45
+ # @extension No idea
46
+ # @return [Array] Array of current fcns to be added.
19
47
  def cachely(fcn, opts = {}, &extension)
20
- @cachely_fcns_added ||= []
21
- @cachely_fcns = []
48
+ @cachely_fcns ||= []
49
+ @cachely_opts ||= {}
50
+
22
51
  @cachely_fcns << fcn
52
+ @cachely_opts[fcn] = opts
23
53
  end
24
54
  end
25
55
 
@@ -0,0 +1,218 @@
1
+ #place all mechanics methods here bc we do not want to introduce random method namespaces to objects
2
+ module Cachely
3
+ module Mechanics
4
+
5
+ # Connects to the Redis store you want to use for a cache.
6
+ #
7
+ # @opt [Hash<Symbol>]
8
+ # @return [Boolean] success or not
9
+ def self.connect(opts = {})
10
+ @redis ||= Redis.new(
11
+ :host => opts[:host],
12
+ :port => opts[:port],
13
+ :password => opts[:password],
14
+ :driver => opts[:driver])
15
+ end
16
+
17
+ # Flush the Redis store of all keys.
18
+ #
19
+ # @return [String] success or not, normally "OK"
20
+ def self.flush_all_keys
21
+ redis.flushdb
22
+ end
23
+
24
+ # Grab current redis instance. Has ability to reconnect for you if it fails.
25
+ #
26
+ # @return [Redis], instance of Redis client.
27
+ def self.redis
28
+ @tries = 0 unless @tries
29
+ begin
30
+ @redis.get("test") #tests to see if we're still authed.
31
+ @tries = 0 #means we can reset our trymeter.
32
+ rescue Exception => e
33
+ @tries+=1 if @tries
34
+ if @tries<5
35
+ connect
36
+ end
37
+ end
38
+ return @redis
39
+ end
40
+
41
+ # Defines the method using my hacky eval script. So far, this is the only way I've found that
42
+ # allows me to define variable argument length definitions. If you have a better idea, please
43
+ # refactor it!
44
+ #
45
+ # @name [Symbol] fcn name
46
+ # @return nil
47
+ def self.setup_method(klazz, name, time_to_expire_in_s, is_class_method = false)
48
+ context = (is_class_method ? klazz : klazz.new)
49
+ args_str = context.method("#{name.to_s}_old".to_sym).parameters.map { |k| k.last}.join(',')
50
+ args_to_use_in_def = args_str.empty? ? "" : "," + args_str
51
+ eval("klazz.define_#{is_class_method ? "singleton_" : ""}method(:#{name}) do #{args_str.empty? ? "" : "|#{args_str}|"}; " +
52
+ "result = Cachely::Mechanics.get(context,:#{name}#{args_to_use_in_def});" +
53
+ "return result.first if result.is_a?(Array);" +
54
+ "result = context.send(:#{"#{name.to_s}_old"}#{args_to_use_in_def});" +
55
+ "Cachely::Mechanics.store(context,:#{"#{name.to_s}"}, result#{time_to_expire_in_s.nil? ? ",nil": ",#{time_to_expire_in_s}"}#{args_to_use_in_def});" +
56
+ "return result;" +
57
+ "end"
58
+ )
59
+ end
60
+
61
+ # Gets a cached response to a method.
62
+ #
63
+ # @method [String,Symbol] the method name
64
+ # @args The arguments of the method
65
+ # @return The original response of the method back, whatever it may be.
66
+ def self.get(obj, method, *args)
67
+ result = redis.get(redis_key(obj, method, *args))
68
+ #return an array, bc if the result stored was nil, it looks the same as if
69
+ #we got no result back(which we would return nil) so we differentiate by putting
70
+ #our return value always in an array. Easy to check.
71
+ result.nil? ? nil : [map_s_to_param(result)]
72
+ end
73
+
74
+ # Stores the result in it's proper cached location on redis by getting the redis key and parsing
75
+ # The result into a storable string, mostly made up of recursive json.
76
+ #
77
+ # @method [Symbol] Method name
78
+ # @result Anything, really.
79
+ # @args Arguments of the method
80
+ # @return [String] Should be "Ok" or something similar.
81
+ def self.store(obj, method, result, time_to_exp_in_sec, *args)
82
+ redis.set(redis_key(obj, method, *args), map_param_to_s(result))
83
+ redis.expire(redis_key(obj, method, *args), time_to_exp_in_sec) if time_to_exp_in_sec
84
+ end
85
+
86
+ # Converts method name and arguments into a coherent key. Creates a hash and to_jsons it
87
+ # And that becomes the redis key. Spiffy, I know.
88
+ #
89
+ # @method [String,Symbol] The method name
90
+ # @return [String] The proper redis key to be used in storage.
91
+ def self.redis_key(obj, method, *args)
92
+ map_param_to_s({
93
+ :obj => obj.to_s.match(/^#</) ? "instance:#{obj.class}" : obj.to_s,
94
+ :attributes => obj.to_json, #Best way to identify objects is to just to_json them.
95
+ :method => method,
96
+ :args => args
97
+ })
98
+ end
99
+
100
+ # Turns any string into a parameter. Current supported types are primitives, orm models
101
+ # That respond to id and have an updated_at field, and objects that have a to_json method.
102
+ #
103
+ # @s The string to convert
104
+ # @return [Object] The respawned object
105
+ def self.map_s_to_param(s)
106
+ begin
107
+ respawned_hash = JSON.parse(s)
108
+
109
+ if respawned_hash.is_a?(Array)
110
+ respawned_hash.map! do |piece|
111
+ map_s_to_param(piece)
112
+ end
113
+ elsif respawned_hash.is_a?(Hash)
114
+ respawned_hash = respawned_hash.inject(Hash.new) do |new_hash, entry|
115
+ new_hash[map_s_to_param(entry[0])] = map_s_to_param(entry[1])
116
+ new_hash
117
+ end
118
+ end
119
+
120
+ return respawned_hash
121
+ rescue JSON::ParserError => e
122
+ #The only times the string isn't json is if it is a primitive, or an ORM object
123
+ #This exception happens then, we catch it, and check orm signature.
124
+
125
+ return map_s_to_obj(s)
126
+ end
127
+
128
+ end
129
+
130
+ # Turns String into an actual object
131
+ #
132
+ # @s The string to convert
133
+ # @return The respawned object
134
+ def self.map_s_to_obj(s)
135
+ type = s.split(":").first
136
+ data = s.gsub(/^#{type}:/,'')
137
+
138
+ case type
139
+ when "TrueClass"
140
+ return true
141
+ when "FalseClass"
142
+ return false
143
+ when "Symbol"
144
+ return data.to_sym
145
+ when "Fixnum"
146
+ return data.to_i
147
+ when "Float"
148
+ return data.to_f
149
+ when "String"
150
+ return data
151
+ when "NilClass"
152
+ return nil
153
+ else
154
+ obj = Object.const_get(type).new
155
+ JSON.parse(data).each do |key, value|
156
+ obj.send(key+"=",value)
157
+ end
158
+ return obj
159
+ end
160
+ end
161
+
162
+ # Turns any parameter into a string. Current supported types are primitives, orm models
163
+ # That respond to id and have an updated_at field, and objects that have a to_json method.
164
+ #
165
+ # @p The object to convert
166
+ # @return [String] The redis coded string.
167
+ def self.map_param_to_s(p)
168
+ if(p.is_a?(Hash))
169
+ return map_hash_to_s(p)
170
+ elsif(p.is_a?(Array))
171
+ return map_array_to_s(p)
172
+ elsif(p.respond_to?("to_json"))
173
+ #below do extra search if string bc string puts annoying quotes in json like "\"1\""
174
+ #breaks the parser on the return translation.
175
+ translated = nil
176
+ if p.is_a?(String)
177
+ translated = p
178
+ elsif p.is_a?(Symbol)
179
+ translated = p.to_s
180
+ elsif p.nil?
181
+ translated = "nil"
182
+ elsif p.is_a?(ActiveRecord::Base)
183
+ #don't want { "dummy_model" = > {:attributes => 1}}
184
+ #want {:attributes => 1}
185
+ translated = JSON.parse(p.to_json)[p.class.to_s.underscore].to_json
186
+ else
187
+ translated = p.to_json
188
+ end
189
+
190
+ return p.class.to_s + ":" + translated
191
+ end
192
+ end
193
+
194
+ # Maps hash to s, basically does recursive call to map_param_to_s to get everythign inside
195
+ # and then to_jsons.
196
+ #
197
+ # @p [Hash] Incoming hash
198
+ # @return [String] Outgoing redis string
199
+ def self.map_hash_to_s(p)
200
+ p.inject(Hash.new) do |hash, entry|
201
+ hash[map_param_to_s(entry[0])] = map_param_to_s(entry[1])
202
+ hash
203
+ end.to_json
204
+ end
205
+
206
+ # Map array to s, calls recursively on elements then to json
207
+ #
208
+ # @p [Array] Incoming array
209
+ # @return [String] Outgoing redis string
210
+ def self.map_array_to_s(p)
211
+ p.map do |part|
212
+ map_param_to_s(part)
213
+ end.to_json
214
+ end
215
+
216
+
217
+ end
218
+ end
@@ -1,3 +1,3 @@
1
1
  module Cachely
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -1,92 +1,455 @@
1
1
  class DummyClass
2
2
  include Cachely
3
- cachely :test_function_num, time: 3.minutes
4
- #cachely :test_function_array, time: 2.minutes
5
- #cachely :test_function_hash, time: 2.minutes
6
- #cachely :test_function_string, time: 3.minutes
7
- #cachely :test_function_obj, time: 4.minutes
8
- #cachely :test_function_array_obj, time: 5.minutes
9
- #cachely :test_function_hash_obj, time: 6.minutes
10
-
11
- def test_function_num
3
+ attr_accessor :random_no
4
+
5
+ cachely :cache_expiry, time_to_expiry: 1.seconds
6
+
7
+ cachely :class_diff, time_to_expiry: 3.minutes
8
+
9
+ cachely :instance_only_cache, time_to_expiry: 3.minutes, type: "instance"
10
+ cachely :class_only_cache, time_to_expiry: 3.minutes, type: "class"
11
+
12
+ cachely :instance_fixnum, time_to_expiry: 3.minutes
13
+ cachely :instance_fixnum_one, time_to_expiry: 3.minutes
14
+ cachely :instance_fixnum_two, time_to_expiry: 3.minutes
15
+
16
+ cachely :instance_float, time_to_expiry: 3.minutes
17
+ cachely :instance_float_one, time_to_expiry: 3.minutes
18
+ cachely :instance_float_two, time_to_expiry: 3.minutes
19
+
20
+ cachely :instance_string, time_to_expiry: 3.minutes
21
+ cachely :instance_string_one, time_to_expiry: 3.minutes
22
+ cachely :instance_string_two, time_to_expiry: 3.minutes
23
+
24
+ cachely :instance_symbol, time_to_expiry: 3.minutes
25
+ cachely :instance_symbol_one, time_to_expiry: 3.minutes
26
+ cachely :instance_symbol_two, time_to_expiry: 3.minutes
27
+
28
+ cachely :instance_nilclass, time_to_expiry: 3.minutes
29
+ cachely :instance_nilclass_one, time_to_expiry: 3.minutes
30
+ cachely :instance_nilclass_two, time_to_expiry: 3.minutes
31
+
32
+ cachely :instance_falseclass, time_to_expiry: 3.minutes
33
+ cachely :instance_falseclass_one, time_to_expiry: 3.minutes
34
+ cachely :instance_falseclass_two, time_to_expiry: 3.minutes
35
+
36
+ cachely :instance_trueclass, time_to_expiry: 3.minutes
37
+ cachely :instance_trueclass_one, time_to_expiry: 3.minutes
38
+ cachely :instance_trueclass_two, time_to_expiry: 3.minutes
39
+
40
+ cachely :instance_orm, time_to_expiry: 3.minutes
41
+ cachely :instance_orm_one, time_to_expiry: 3.minutes
42
+ cachely :instance_orm_two, time_to_expiry: 3.minutes
43
+
44
+ cachely :instance_array, time_to_expiry: 3.minutes
45
+ cachely :instance_array_one, time_to_expiry: 3.minutes
46
+ cachely :instance_array_two, time_to_expiry: 3.minutes
47
+
48
+ cachely :instance_hash, time_to_expiry: 3.minutes
49
+ cachely :instance_hash_one, time_to_expiry: 3.minutes
50
+ cachely :instance_hash_two, time_to_expiry: 3.minutes
51
+
52
+ cachely :instance_to_json, time_to_expiry: 3.minutes
53
+ cachely :instance_to_json_one, time_to_expiry: 3.minutes
54
+ cachely :instance_to_json_two, time_to_expiry: 3.minutes
55
+
56
+ cachely :class_fixnum, time_to_expiry: 3.minutes
57
+ cachely :class_fixnum_one, time_to_expiry: 3.minutes
58
+ cachely :class_fixnum_two, time_to_expiry: 3.minutes
59
+
60
+ cachely :class_float, time_to_expiry: 3.minutes
61
+ cachely :class_float_one, time_to_expiry: 3.minutes
62
+ cachely :class_float_two, time_to_expiry: 3.minutes
63
+
64
+ cachely :class_string, time_to_expiry: 3.minutes
65
+ cachely :class_string_one, time_to_expiry: 3.minutes
66
+ cachely :class_string_two, time_to_expiry: 3.minutes
67
+
68
+ cachely :class_symbol, time_to_expiry: 3.minutes
69
+ cachely :class_symbol_one, time_to_expiry: 3.minutes
70
+ cachely :class_symbol_two, time_to_expiry: 3.minutes
71
+
72
+ cachely :class_nilclass, time_to_expiry: 3.minutes
73
+ cachely :class_nilclass_one, time_to_expiry: 3.minutes
74
+ cachely :class_nilclass_two, time_to_expiry: 3.minutes
75
+
76
+ cachely :class_falseclass, time_to_expiry: 3.minutes
77
+ cachely :class_falseclass_one, time_to_expiry: 3.minutes
78
+ cachely :class_falseclass_two, time_to_expiry: 3.minutes
79
+
80
+ cachely :class_trueclass, time_to_expiry: 3.minutes
81
+ cachely :class_trueclass_one, time_to_expiry: 3.minutes
82
+ cachely :class_trueclass_two, time_to_expiry: 3.minutes
83
+
84
+ cachely :class_orm, time_to_expiry: 3.minutes
85
+ cachely :class_orm_one, time_to_expiry: 3.minutes
86
+ cachely :class_orm_two, time_to_expiry: 3.minutes
87
+
88
+ cachely :class_array, time_to_expiry: 3.minutes
89
+ cachely :class_array_one, time_to_expiry: 3.minutes
90
+ cachely :class_array_two, time_to_expiry: 3.minutes
91
+
92
+ cachely :class_hash, time_to_expiry: 3.minutes
93
+ cachely :class_hash_one, time_to_expiry: 3.minutes
94
+ cachely :class_hash_two, time_to_expiry: 3.minutes
95
+
96
+ cachely :class_to_json, time_to_expiry: 3.minutes
97
+ cachely :class_to_json_one, time_to_expiry: 3.minutes
98
+ cachely :class_to_json_two, time_to_expiry: 3.minutes
99
+
100
+ def to_json
101
+ {
102
+ "random_no" => self.random_no
103
+ }.to_json
104
+ end
105
+
106
+ def instance_only_cache
12
107
  rand(500)
13
108
  end
14
-
15
- def self.class_test_function_num
109
+
110
+ def self.instance_only_cache
16
111
  rand(500)
17
112
  end
18
-
19
- def self.class_test_function_not_cached
113
+
114
+ def class_only_cache
20
115
  rand(500)
21
116
  end
22
-
23
- def test_function_not_cached
117
+
118
+ def self.class_only_cache
24
119
  rand(500)
25
120
  end
26
-
27
- def test_function_array
28
- [1,2,3,4,5,6, rand(500)]
121
+
122
+ def self.class_diff
123
+ rand(500)
29
124
  end
30
-
31
- def self.class_test_function_array
32
- [1,2,3,4,5,6, rand(500)]
125
+
126
+ def class_diff
127
+ rand(500)
33
128
  end
34
-
35
- def test_function_hash
36
- {
37
- :foo => "bar#{rand(500)}",
38
- :baz => "boof"
39
- }
129
+
130
+ def cache_expiry
131
+ rand(500)
40
132
  end
41
-
42
- def self.class_test_function_hash
43
- {
44
- :foo => "bar#{rand(500)}",
45
- :baz => "boof"
46
- }
47
- end
48
-
49
- def test_function_string
50
- rand(500).to_s
51
- end
52
-
53
- def self.class_test_function_string
54
- rand(500).to_s
55
- end
56
-
57
- def test_function_obj
58
- DummyModel.create(
59
- :attr1 => rand(500),
60
- :attr2 => rand(500)
61
- )
62
- end
63
-
64
- def self.class_test_function_obj
65
- DummyModel.create(
66
- :attr1 => rand(500),
67
- :attr2 => rand(500)
68
- )
69
- end
70
-
71
- def test_function_array_obj
72
- [test_function_obj, test_function_obj]
73
- end
74
-
75
- def self.class_test_function_array_obj
76
- [test_function_obj, test_function_obj]
77
- end
78
-
79
- def test_function_hash_obj
80
- {
81
- :foo => test_function_obj,
82
- :bar => test_function_obj
83
- }
133
+
134
+ def instance_fixnum
135
+ rand(500)
84
136
  end
85
-
86
- def self.class_test_function_hash_obj
87
- {
88
- :foo => test_function_obj,
89
- :bar => test_function_obj
90
- }
137
+
138
+ def instance_fixnum_one(a)
139
+ rand(500)
140
+ end
141
+
142
+ def instance_fixnum_two(a,b)
143
+ rand(500)
144
+ end
145
+
146
+ def instance_float
147
+ rand(500).to_f + 0.5
148
+ end
149
+
150
+ def instance_float_one(a)
151
+ rand(500).to_f + 0.5
152
+ end
153
+
154
+ def instance_float_two(a,b)
155
+ rand(500).to_f + 0.5
156
+ end
157
+
158
+ def instance_string
159
+ rand(500).to_s + "cheese"
160
+ end
161
+
162
+ def instance_string_one(a)
163
+ rand(500).to_s + "cheese"
164
+ end
165
+
166
+ def instance_string_two(a,b)
167
+ rand(500).to_s + "cheese"
168
+ end
169
+
170
+ def instance_symbol
171
+ "cheese#{rand(500)}".to_sym
172
+ end
173
+
174
+ def instance_symbol_one(a)
175
+ "cheese#{rand(500)}".to_sym
176
+ end
177
+
178
+ def instance_symbol_two(a,b)
179
+ "cheese#{rand(500)}".to_sym
180
+ end
181
+
182
+ def instance_nilclass #force it to be nil ONLY once to check caching ability.
183
+ @@set_nilclass_0 ||= false
184
+ p "i am false now " if @@set_nilclass_0
185
+ return "1" if @@set_nilclass_0
186
+ @@set_nilclass_0 = true
187
+ nil
188
+ end
189
+
190
+ def instance_nilclass_one(a)
191
+ @@set_nilclass_1 ||= false
192
+ p "i am false now " if @@set_nilclass_1
193
+ return "1" if @@set_nilclass_1
194
+ @@set_nilclass_1 = true
195
+ nil end
196
+
197
+ def instance_nilclass_two(a,b)
198
+ @@set_nilclass_2 ||= false
199
+ p "i am false now " if @@set_nilclass_2
200
+ return "1" if @@set_nilclass_2
201
+ @@set_nilclass_2 = true
202
+ nil
203
+ end
204
+
205
+ def instance_falseclass
206
+ @@set_falseclass_0 ||= false
207
+ return true if @@set_falseclass_0
208
+ @@set_falseclass_0 = true
209
+ false
210
+ end
211
+
212
+ def instance_falseclass_one(a)
213
+ @@set_falseclass_1 ||= false
214
+ return true if @@set_falseclass_1
215
+ @@set_falseclass_1 = true
216
+ false
217
+ end
218
+
219
+ def instance_falseclass_two(a,b)
220
+ @@set_falseclass_2 ||= false
221
+ return true if @@set_falseclass_2
222
+ @@set_falseclass_2 = true
223
+ false
224
+ end
225
+
226
+ def instance_trueclass
227
+ @@set_trueclass_0 ||= false
228
+ return false if @@set_trueclass_0
229
+ @@set_trueclass_0 = true
230
+ true
231
+ end
232
+
233
+ def instance_trueclass_one(a)
234
+ @@set_trueclass_1 ||= false
235
+ return false if @@set_trueclass_1
236
+ @@set_trueclass_1 = true
237
+ true
238
+ end
239
+
240
+ def instance_trueclass_two(a,b)
241
+ @@set_trueclass_2 ||= false
242
+ return false if @@set_trueclass_2
243
+ @@set_trueclass_2 = true
244
+ true
245
+ end
246
+
247
+ def instance_orm
248
+ DummyModel.create!(:attr_1 => rand(500), :attr_2 => rand(500))
249
+ end
250
+
251
+ def instance_orm_one(a)
252
+ DummyModel.create!(:attr_1 => rand(500), :attr_2 => rand(500))
253
+ end
254
+
255
+ def instance_orm_two(a,b)
256
+ DummyModel.create!(:attr_1 => rand(500), :attr_2 => rand(500))
257
+ end
258
+
259
+ def instance_to_json
260
+ DummyClass.new
261
+ end
262
+
263
+ def instance_to_json_one(a)
264
+ DummyClass.new
265
+ end
266
+
267
+ def instance_to_json_two(a,b)
268
+ DummyClass.new
269
+ end
270
+
271
+ def instance_hash
272
+ {:foo => rand(500)}
273
+ end
274
+
275
+ def instance_hash_one(a)
276
+ {:foo => rand(500)}
277
+ end
278
+
279
+ def instance_hash_two(a,b)
280
+ {:foo => rand(500)}
281
+ end
282
+
283
+ def instance_array
284
+ [rand(500)]
285
+ end
286
+
287
+ def instance_array_one(a)
288
+ [rand(500)]
289
+ end
290
+
291
+ def instance_array_two(a,b)
292
+ [rand(500)]
293
+ end
294
+
295
+ def self.class_fixnum
296
+ rand(500)
297
+ end
298
+
299
+ def self.class_fixnum_one(a)
300
+ rand(500)
301
+ end
302
+
303
+ def self.class_fixnum_two(a,b)
304
+ rand(500)
305
+ end
306
+
307
+ def self.class_float
308
+ rand(500).to_f + 0.5
309
+ end
310
+
311
+ def self.class_float_one(a)
312
+ rand(500).to_f + 0.5
313
+ end
314
+
315
+ def self.class_float_two(a,b)
316
+ rand(500).to_f + 0.5
317
+ end
318
+
319
+ def self.class_string
320
+ rand(500).to_s + "cheese"
321
+ end
322
+
323
+ def self.class_string_one(a)
324
+ rand(500).to_s + "cheese"
325
+ end
326
+
327
+ def self.class_string_two(a,b)
328
+ rand(500).to_s + "cheese"
329
+ end
330
+
331
+ def self.class_symbol
332
+ "cheese#{rand(500)}".to_sym
333
+ end
334
+
335
+ def self.class_symbol_one(a)
336
+ "cheese#{rand(500)}".to_sym
337
+ end
338
+
339
+ def self.class_symbol_two(a,b)
340
+ "cheese#{rand(500)}".to_sym
341
+ end
342
+
343
+ def self.class_nilclass #force it to be nil ONLY once to check caching ability.
344
+ @@set_nilclass_0 ||= false
345
+ p "i am false now " if @@set_nilclass_0
346
+ return "1" if @@set_nilclass_0
347
+ @@set_nilclass_0 = true
348
+ nil
349
+ end
350
+
351
+ def self.class_nilclass_one(a)
352
+ @@set_nilclass_1 ||= false
353
+ p "i am false now " if @@set_nilclass_1
354
+ return "1" if @@set_nilclass_1
355
+ @@set_nilclass_1 = true
356
+ nil end
357
+
358
+ def self.class_nilclass_two(a,b)
359
+ @@set_nilclass_2 ||= false
360
+ p "i am false now " if @@set_nilclass_2
361
+ return "1" if @@set_nilclass_2
362
+ @@set_nilclass_2 = true
363
+ nil
364
+ end
365
+
366
+ def self.class_falseclass
367
+ @@set_falseclass_0 ||= false
368
+ return true if @@set_falseclass_0
369
+ @@set_falseclass_0 = true
370
+ false
371
+ end
372
+
373
+ def self.class_falseclass_one(a)
374
+ @@set_falseclass_1 ||= false
375
+ return true if @@set_falseclass_1
376
+ @@set_falseclass_1 = true
377
+ false
378
+ end
379
+
380
+ def self.class_falseclass_two(a,b)
381
+ @@set_falseclass_2 ||= false
382
+ return true if @@set_falseclass_2
383
+ @@set_falseclass_2 = true
384
+ false
385
+ end
386
+
387
+ def self.class_trueclass
388
+ @@set_trueclass_0 ||= false
389
+ return false if @@set_trueclass_0
390
+ @@set_trueclass_0 = true
391
+ true
392
+ end
393
+
394
+ def self.class_trueclass_one(a)
395
+ @@set_trueclass_1 ||= false
396
+ return false if @@set_trueclass_1
397
+ @@set_trueclass_1 = true
398
+ true
399
+ end
400
+
401
+ def self.class_trueclass_two(a,b)
402
+ @@set_trueclass_2 ||= false
403
+ return false if @@set_trueclass_2
404
+ @@set_trueclass_2 = true
405
+ true
406
+ end
407
+
408
+ def self.class_orm
409
+ DummyModel.create!(:attr_1 => rand(500), :attr_2 => rand(500))
410
+ end
411
+
412
+ def self.class_orm_one(a)
413
+ DummyModel.create!(:attr_1 => rand(500), :attr_2 => rand(500))
414
+ end
415
+
416
+ def self.class_orm_two(a,b)
417
+ DummyModel.create!(:attr_1 => rand(500), :attr_2 => rand(500))
418
+ end
419
+
420
+ def self.class_to_json
421
+ DummyClass.new
422
+ end
423
+
424
+ def self.class_to_json_one(a)
425
+ DummyClass.new
426
+ end
427
+
428
+ def self.class_to_json_two(a,b)
429
+ DummyClass.new
430
+ end
431
+
432
+ def self.class_hash
433
+ {:foo => rand(500)}
434
+ end
435
+
436
+ def self.class_hash_one(a)
437
+ {:foo => rand(500)}
438
+ end
439
+
440
+ def self.class_hash_two(a,b)
441
+ {:foo => rand(500)}
442
+ end
443
+
444
+ def self.class_array
445
+ [rand(500)]
446
+ end
447
+
448
+ def self.class_array_one(a)
449
+ [rand(500)]
450
+ end
451
+
452
+ def self.class_array_two(a,b)
453
+ [rand(500)]
91
454
  end
92
455
  end