esod-client 0.1.0

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.
Files changed (83) hide show
  1. data/EXAMPLES +140 -0
  2. data/GEM_RELEASE +19 -0
  3. data/README +10 -0
  4. data/Rakefile +14 -0
  5. data/VERSION +1 -0
  6. data/esod-client.gemspec +118 -0
  7. data/esod-client.rb +35 -0
  8. data/lib/activesupport-2.2.2/CHANGELOG +1257 -0
  9. data/lib/activesupport-2.2.2/README +43 -0
  10. data/lib/activesupport-2.2.2/README.CFT +2 -0
  11. data/lib/activesupport-2.2.2/lib/active_support.rb +26 -0
  12. data/lib/activesupport-2.2.2/lib/active_support/base64.rb +33 -0
  13. data/lib/activesupport-2.2.2/lib/active_support/basic_object.rb +24 -0
  14. data/lib/activesupport-2.2.2/lib/active_support/buffered_logger.rb +122 -0
  15. data/lib/activesupport-2.2.2/lib/active_support/cache.rb +223 -0
  16. data/lib/activesupport-2.2.2/lib/active_support/cache/compressed_mem_cache_store.rb +20 -0
  17. data/lib/activesupport-2.2.2/lib/active_support/cache/drb_store.rb +15 -0
  18. data/lib/activesupport-2.2.2/lib/active_support/cache/file_store.rb +72 -0
  19. data/lib/activesupport-2.2.2/lib/active_support/cache/mem_cache_store.rb +127 -0
  20. data/lib/activesupport-2.2.2/lib/active_support/cache/memory_store.rb +52 -0
  21. data/lib/activesupport-2.2.2/lib/active_support/cache/synchronized_memory_store.rb +47 -0
  22. data/lib/activesupport-2.2.2/lib/active_support/callbacks.rb +280 -0
  23. data/lib/activesupport-2.2.2/lib/active_support/core_ext.rb +6 -0
  24. data/lib/activesupport-2.2.2/lib/active_support/core_ext/hash.rb +14 -0
  25. data/lib/activesupport-2.2.2/lib/active_support/core_ext/hash/conversions.rb +259 -0
  26. data/lib/activesupport-2.2.2/lib/active_support/core_ext/hash/deep_merge.rb +23 -0
  27. data/lib/activesupport-2.2.2/lib/active_support/core_ext/hash/diff.rb +19 -0
  28. data/lib/activesupport-2.2.2/lib/active_support/core_ext/hash/except.rb +25 -0
  29. data/lib/activesupport-2.2.2/lib/active_support/core_ext/hash/indifferent_access.rb +137 -0
  30. data/lib/activesupport-2.2.2/lib/active_support/core_ext/hash/keys.rb +52 -0
  31. data/lib/activesupport-2.2.2/lib/active_support/core_ext/hash/reverse_merge.rb +35 -0
  32. data/lib/activesupport-2.2.2/lib/active_support/core_ext/hash/slice.rb +33 -0
  33. data/lib/activesupport-2.2.2/lib/active_support/vendor.rb +14 -0
  34. data/lib/activesupport-2.2.2/lib/active_support/vendor/builder-2.1.2/blankslate.rb +113 -0
  35. data/lib/activesupport-2.2.2/lib/active_support/vendor/builder-2.1.2/builder.rb +13 -0
  36. data/lib/activesupport-2.2.2/lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb +20 -0
  37. data/lib/activesupport-2.2.2/lib/active_support/vendor/builder-2.1.2/builder/css.rb +250 -0
  38. data/lib/activesupport-2.2.2/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb +115 -0
  39. data/lib/activesupport-2.2.2/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb +139 -0
  40. data/lib/activesupport-2.2.2/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb +63 -0
  41. data/lib/activesupport-2.2.2/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb +328 -0
  42. data/lib/activesupport-2.2.2/lib/active_support/vendor/xml-simple-1.0.11/xmlsimple.rb +1021 -0
  43. data/lib/activesupport-2.2.2/lib/activesupport.rb +1 -0
  44. data/lib/esodclient/esodclient.rb +22 -0
  45. data/lib/hash.rb +22 -0
  46. data/lib/mime-types-1.16/History.txt +107 -0
  47. data/lib/mime-types-1.16/Install.txt +17 -0
  48. data/lib/mime-types-1.16/Licence.txt +15 -0
  49. data/lib/mime-types-1.16/Manifest.txt +12 -0
  50. data/lib/mime-types-1.16/README.txt +28 -0
  51. data/lib/mime-types-1.16/Rakefile +316 -0
  52. data/lib/mime-types-1.16/lib/mime/types.rb +751 -0
  53. data/lib/mime-types-1.16/lib/mime/types.rb.data +1324 -0
  54. data/lib/mime-types-1.16/mime-types.gemspec +43 -0
  55. data/lib/mime-types-1.16/setup.rb +1585 -0
  56. data/lib/mime-types-1.16/test/test_mime_type.rb +356 -0
  57. data/lib/mime-types-1.16/test/test_mime_types.rb +122 -0
  58. data/lib/rest-client-1.2.0/README.rdoc +102 -0
  59. data/lib/rest-client-1.2.0/Rakefile +57 -0
  60. data/lib/rest-client-1.2.0/VERSION +1 -0
  61. data/lib/rest-client-1.2.0/bin/restclient +87 -0
  62. data/lib/rest-client-1.2.0/lib/rest_client.rb +2 -0
  63. data/lib/rest-client-1.2.0/lib/restclient.rb +108 -0
  64. data/lib/rest-client-1.2.0/lib/restclient/exceptions.rb +89 -0
  65. data/lib/rest-client-1.2.0/lib/restclient/mixin/response.rb +48 -0
  66. data/lib/rest-client-1.2.0/lib/restclient/net_http_ext.rb +21 -0
  67. data/lib/rest-client-1.2.0/lib/restclient/payload.rb +178 -0
  68. data/lib/rest-client-1.2.0/lib/restclient/raw_response.rb +30 -0
  69. data/lib/rest-client-1.2.0/lib/restclient/request.rb +287 -0
  70. data/lib/rest-client-1.2.0/lib/restclient/resource.rb +146 -0
  71. data/lib/rest-client-1.2.0/lib/restclient/response.rb +20 -0
  72. data/lib/rest-client-1.2.0/spec/base.rb +10 -0
  73. data/lib/rest-client-1.2.0/spec/exceptions_spec.rb +65 -0
  74. data/lib/rest-client-1.2.0/spec/master_shake.jpg +0 -0
  75. data/lib/rest-client-1.2.0/spec/mixin/response_spec.rb +46 -0
  76. data/lib/rest-client-1.2.0/spec/payload_spec.rb +131 -0
  77. data/lib/rest-client-1.2.0/spec/raw_response_spec.rb +17 -0
  78. data/lib/rest-client-1.2.0/spec/request_spec.rb +521 -0
  79. data/lib/rest-client-1.2.0/spec/resource_spec.rb +75 -0
  80. data/lib/rest-client-1.2.0/spec/response_spec.rb +21 -0
  81. data/lib/rest-client-1.2.0/spec/restclient_spec.rb +53 -0
  82. data/lib/trollop/trollop.rb +735 -0
  83. metadata +137 -0
@@ -0,0 +1,20 @@
1
+ module ActiveSupport
2
+ module Cache
3
+ class CompressedMemCacheStore < MemCacheStore
4
+ def read(name, options = nil)
5
+ if value = super(name, (options || {}).merge(:raw => true))
6
+ if raw?(options)
7
+ value
8
+ else
9
+ Marshal.load(ActiveSupport::Gzip.decompress(value))
10
+ end
11
+ end
12
+ end
13
+
14
+ def write(name, value, options = nil)
15
+ value = ActiveSupport::Gzip.compress(Marshal.dump(value)) unless raw?(options)
16
+ super(name, value, (options || {}).merge(:raw => true))
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ require 'drb'
2
+
3
+ module ActiveSupport
4
+ module Cache
5
+ class DRbStore < MemoryStore #:nodoc:
6
+ attr_reader :address
7
+
8
+ def initialize(address = 'druby://localhost:9192')
9
+ super()
10
+ @address = address
11
+ @data = DRbObject.new(nil, address)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,72 @@
1
+ module ActiveSupport
2
+ module Cache
3
+ # A cache store implementation which stores everything on the filesystem.
4
+ class FileStore < Store
5
+ attr_reader :cache_path
6
+
7
+ def initialize(cache_path)
8
+ @cache_path = cache_path
9
+ end
10
+
11
+ def read(name, options = nil)
12
+ super
13
+ File.open(real_file_path(name), 'rb') { |f| Marshal.load(f) } rescue nil
14
+ end
15
+
16
+ def write(name, value, options = nil)
17
+ super
18
+ ensure_cache_path(File.dirname(real_file_path(name)))
19
+ File.atomic_write(real_file_path(name), cache_path) { |f| Marshal.dump(value, f) }
20
+ value
21
+ rescue => e
22
+ logger.error "Couldn't create cache directory: #{name} (#{e.message})" if logger
23
+ end
24
+
25
+ def delete(name, options = nil)
26
+ super
27
+ File.delete(real_file_path(name))
28
+ rescue SystemCallError => e
29
+ # If there's no cache, then there's nothing to complain about
30
+ end
31
+
32
+ def delete_matched(matcher, options = nil)
33
+ super
34
+ search_dir(@cache_path) do |f|
35
+ if f =~ matcher
36
+ begin
37
+ File.delete(f)
38
+ rescue SystemCallError => e
39
+ # If there's no cache, then there's nothing to complain about
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ def exist?(name, options = nil)
46
+ super
47
+ File.exist?(real_file_path(name))
48
+ end
49
+
50
+ private
51
+ def real_file_path(name)
52
+ '%s/%s.cache' % [@cache_path, name.gsub('?', '.').gsub(':', '.')]
53
+ end
54
+
55
+ def ensure_cache_path(path)
56
+ FileUtils.makedirs(path) unless File.exist?(path)
57
+ end
58
+
59
+ def search_dir(dir, &callback)
60
+ Dir.foreach(dir) do |d|
61
+ next if d == "." || d == ".."
62
+ name = File.join(dir, d)
63
+ if File.directory?(name)
64
+ search_dir(name, &callback)
65
+ else
66
+ callback.call name
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,127 @@
1
+ require 'memcache'
2
+
3
+ module ActiveSupport
4
+ module Cache
5
+ # A cache store implementation which stores data in Memcached:
6
+ # http://www.danga.com/memcached/
7
+ #
8
+ # This is currently the most popular cache store for production websites.
9
+ #
10
+ # Special features:
11
+ # - Clustering and load balancing. One can specify multiple memcached servers,
12
+ # and MemCacheStore will load balance between all available servers. If a
13
+ # server goes down, then MemCacheStore will ignore it until it goes back
14
+ # online.
15
+ # - Time-based expiry support. See #write and the +:expires_in+ option.
16
+ class MemCacheStore < Store
17
+ module Response # :nodoc:
18
+ STORED = "STORED\r\n"
19
+ NOT_STORED = "NOT_STORED\r\n"
20
+ EXISTS = "EXISTS\r\n"
21
+ NOT_FOUND = "NOT_FOUND\r\n"
22
+ DELETED = "DELETED\r\n"
23
+ end
24
+
25
+ attr_reader :addresses
26
+
27
+ # Creates a new MemCacheStore object, with the given memcached server
28
+ # addresses. Each address is either a host name, or a host-with-port string
29
+ # in the form of "host_name:port". For example:
30
+ #
31
+ # ActiveSupport::Cache::MemCacheStore.new("localhost", "server-downstairs.localnetwork:8229")
32
+ #
33
+ # If no addresses are specified, then MemCacheStore will connect to
34
+ # localhost port 11211 (the default memcached port).
35
+ def initialize(*addresses)
36
+ addresses = addresses.flatten
37
+ options = addresses.extract_options!
38
+ addresses = ["localhost"] if addresses.empty?
39
+ @addresses = addresses
40
+ @data = MemCache.new(addresses, options)
41
+ end
42
+
43
+ def read(key, options = nil) # :nodoc:
44
+ super
45
+ @data.get(key, raw?(options))
46
+ rescue MemCache::MemCacheError => e
47
+ logger.error("MemCacheError (#{e}): #{e.message}")
48
+ nil
49
+ end
50
+
51
+ # Writes a value to the cache.
52
+ #
53
+ # Possible options:
54
+ # - +:unless_exist+ - set to true if you don't want to update the cache
55
+ # if the key is already set.
56
+ # - +:expires_in+ - the number of seconds that this value may stay in
57
+ # the cache. See ActiveSupport::Cache::Store#write for an example.
58
+ def write(key, value, options = nil)
59
+ super
60
+ method = options && options[:unless_exist] ? :add : :set
61
+ # memcache-client will break the connection if you send it an integer
62
+ # in raw mode, so we convert it to a string to be sure it continues working.
63
+ value = value.to_s if raw?(options)
64
+ response = @data.send(method, key, value, expires_in(options), raw?(options))
65
+ response == Response::STORED
66
+ rescue MemCache::MemCacheError => e
67
+ logger.error("MemCacheError (#{e}): #{e.message}")
68
+ false
69
+ end
70
+
71
+ def delete(key, options = nil) # :nodoc:
72
+ super
73
+ response = @data.delete(key, expires_in(options))
74
+ response == Response::DELETED
75
+ rescue MemCache::MemCacheError => e
76
+ logger.error("MemCacheError (#{e}): #{e.message}")
77
+ false
78
+ end
79
+
80
+ def exist?(key, options = nil) # :nodoc:
81
+ # Doesn't call super, cause exist? in memcache is in fact a read
82
+ # But who cares? Reading is very fast anyway
83
+ !read(key, options).nil?
84
+ end
85
+
86
+ def increment(key, amount = 1) # :nodoc:
87
+ log("incrementing", key, amount)
88
+
89
+ response = @data.incr(key, amount)
90
+ response == Response::NOT_FOUND ? nil : response
91
+ rescue MemCache::MemCacheError
92
+ nil
93
+ end
94
+
95
+ def decrement(key, amount = 1) # :nodoc:
96
+ log("decrement", key, amount)
97
+
98
+ response = @data.decr(key, amount)
99
+ response == Response::NOT_FOUND ? nil : response
100
+ rescue MemCache::MemCacheError
101
+ nil
102
+ end
103
+
104
+ def delete_matched(matcher, options = nil) # :nodoc:
105
+ super
106
+ raise "Not supported by Memcache"
107
+ end
108
+
109
+ def clear
110
+ @data.flush_all
111
+ end
112
+
113
+ def stats
114
+ @data.stats
115
+ end
116
+
117
+ private
118
+ def expires_in(options)
119
+ (options && options[:expires_in]) || 0
120
+ end
121
+
122
+ def raw?(options)
123
+ options && options[:raw]
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,52 @@
1
+ module ActiveSupport
2
+ module Cache
3
+ # A cache store implementation which stores everything into memory in the
4
+ # same process. If you're running multiple Ruby on Rails server processes
5
+ # (which is the case if you're using mongrel_cluster or Phusion Passenger),
6
+ # then this means that your Rails server process instances won't be able
7
+ # to share cache data with each other. If your application never performs
8
+ # manual cache item expiry (e.g. when you're using generational cache keys),
9
+ # then using MemoryStore is ok. Otherwise, consider carefully whether you
10
+ # should be using this cache store.
11
+ #
12
+ # MemoryStore is not only able to store strings, but also arbitrary Ruby
13
+ # objects.
14
+ #
15
+ # MemoryStore is not thread-safe. Use SynchronizedMemoryStore instead
16
+ # if you need thread-safety.
17
+ class MemoryStore < Store
18
+ def initialize
19
+ @data = {}
20
+ end
21
+
22
+ def read(name, options = nil)
23
+ super
24
+ @data[name]
25
+ end
26
+
27
+ def write(name, value, options = nil)
28
+ super
29
+ @data[name] = value.freeze
30
+ end
31
+
32
+ def delete(name, options = nil)
33
+ super
34
+ @data.delete(name)
35
+ end
36
+
37
+ def delete_matched(matcher, options = nil)
38
+ super
39
+ @data.delete_if { |k,v| k =~ matcher }
40
+ end
41
+
42
+ def exist?(name,options = nil)
43
+ super
44
+ @data.has_key?(name)
45
+ end
46
+
47
+ def clear
48
+ @data.clear
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,47 @@
1
+ module ActiveSupport
2
+ module Cache
3
+ # Like MemoryStore, but thread-safe.
4
+ class SynchronizedMemoryStore < MemoryStore
5
+ def initialize
6
+ super
7
+ @guard = Monitor.new
8
+ end
9
+
10
+ def fetch(key, options = {})
11
+ @guard.synchronize { super }
12
+ end
13
+
14
+ def read(name, options = nil)
15
+ @guard.synchronize { super }
16
+ end
17
+
18
+ def write(name, value, options = nil)
19
+ @guard.synchronize { super }
20
+ end
21
+
22
+ def delete(name, options = nil)
23
+ @guard.synchronize { super }
24
+ end
25
+
26
+ def delete_matched(matcher, options = nil)
27
+ @guard.synchronize { super }
28
+ end
29
+
30
+ def exist?(name,options = nil)
31
+ @guard.synchronize { super }
32
+ end
33
+
34
+ def increment(key, amount = 1)
35
+ @guard.synchronize { super }
36
+ end
37
+
38
+ def decrement(key, amount = 1)
39
+ @guard.synchronize { super }
40
+ end
41
+
42
+ def clear
43
+ @guard.synchronize { super }
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,280 @@
1
+ module ActiveSupport
2
+ # Callbacks are hooks into the lifecycle of an object that allow you to trigger logic
3
+ # before or after an alteration of the object state.
4
+ #
5
+ # Mixing in this module allows you to define callbacks in your class.
6
+ #
7
+ # Example:
8
+ # class Storage
9
+ # include ActiveSupport::Callbacks
10
+ #
11
+ # define_callbacks :before_save, :after_save
12
+ # end
13
+ #
14
+ # class ConfigStorage < Storage
15
+ # before_save :saving_message
16
+ # def saving_message
17
+ # puts "saving..."
18
+ # end
19
+ #
20
+ # after_save do |object|
21
+ # puts "saved"
22
+ # end
23
+ #
24
+ # def save
25
+ # run_callbacks(:before_save)
26
+ # puts "- save"
27
+ # run_callbacks(:after_save)
28
+ # end
29
+ # end
30
+ #
31
+ # config = ConfigStorage.new
32
+ # config.save
33
+ #
34
+ # Output:
35
+ # saving...
36
+ # - save
37
+ # saved
38
+ #
39
+ # Callbacks from parent classes are inherited.
40
+ #
41
+ # Example:
42
+ # class Storage
43
+ # include ActiveSupport::Callbacks
44
+ #
45
+ # define_callbacks :before_save, :after_save
46
+ #
47
+ # before_save :prepare
48
+ # def prepare
49
+ # puts "preparing save"
50
+ # end
51
+ # end
52
+ #
53
+ # class ConfigStorage < Storage
54
+ # before_save :saving_message
55
+ # def saving_message
56
+ # puts "saving..."
57
+ # end
58
+ #
59
+ # after_save do |object|
60
+ # puts "saved"
61
+ # end
62
+ #
63
+ # def save
64
+ # run_callbacks(:before_save)
65
+ # puts "- save"
66
+ # run_callbacks(:after_save)
67
+ # end
68
+ # end
69
+ #
70
+ # config = ConfigStorage.new
71
+ # config.save
72
+ #
73
+ # Output:
74
+ # preparing save
75
+ # saving...
76
+ # - save
77
+ # saved
78
+ module Callbacks
79
+ class CallbackChain < Array
80
+ def self.build(kind, *methods, &block)
81
+ methods, options = extract_options(*methods, &block)
82
+ methods.map! { |method| Callback.new(kind, method, options) }
83
+ new(methods)
84
+ end
85
+
86
+ def run(object, options = {}, &terminator)
87
+ enumerator = options[:enumerator] || :each
88
+
89
+ unless block_given?
90
+ send(enumerator) { |callback| callback.call(object) }
91
+ else
92
+ send(enumerator) do |callback|
93
+ result = callback.call(object)
94
+ break result if terminator.call(result, object)
95
+ end
96
+ end
97
+ end
98
+
99
+ # TODO: Decompose into more Array like behavior
100
+ def replace_or_append!(chain)
101
+ if index = index(chain)
102
+ self[index] = chain
103
+ else
104
+ self << chain
105
+ end
106
+ self
107
+ end
108
+
109
+ def find(callback, &block)
110
+ select { |c| c == callback && (!block_given? || yield(c)) }.first
111
+ end
112
+
113
+ def delete(callback)
114
+ super(callback.is_a?(Callback) ? callback : find(callback))
115
+ end
116
+
117
+ private
118
+ def self.extract_options(*methods, &block)
119
+ methods.flatten!
120
+ options = methods.extract_options!
121
+ methods << block if block_given?
122
+ return methods, options
123
+ end
124
+
125
+ def extract_options(*methods, &block)
126
+ self.class.extract_options(*methods, &block)
127
+ end
128
+ end
129
+
130
+ class Callback
131
+ attr_reader :kind, :method, :identifier, :options
132
+
133
+ def initialize(kind, method, options = {})
134
+ @kind = kind
135
+ @method = method
136
+ @identifier = options[:identifier]
137
+ @options = options
138
+ end
139
+
140
+ def ==(other)
141
+ case other
142
+ when Callback
143
+ (self.identifier && self.identifier == other.identifier) || self.method == other.method
144
+ else
145
+ (self.identifier && self.identifier == other) || self.method == other
146
+ end
147
+ end
148
+
149
+ def eql?(other)
150
+ self == other
151
+ end
152
+
153
+ def dup
154
+ self.class.new(@kind, @method, @options.dup)
155
+ end
156
+
157
+ def hash
158
+ if @identifier
159
+ @identifier.hash
160
+ else
161
+ @method.hash
162
+ end
163
+ end
164
+
165
+ def call(*args, &block)
166
+ evaluate_method(method, *args, &block) if should_run_callback?(*args)
167
+ rescue LocalJumpError
168
+ raise ArgumentError,
169
+ "Cannot yield from a Proc type filter. The Proc must take two " +
170
+ "arguments and execute #call on the second argument."
171
+ end
172
+
173
+ private
174
+ def evaluate_method(method, *args, &block)
175
+ case method
176
+ when Symbol
177
+ object = args.shift
178
+ object.send(method, *args, &block)
179
+ when String
180
+ eval(method, args.first.instance_eval { binding })
181
+ when Proc, Method
182
+ method.call(*args, &block)
183
+ else
184
+ if method.respond_to?(kind)
185
+ method.send(kind, *args, &block)
186
+ else
187
+ raise ArgumentError,
188
+ "Callbacks must be a symbol denoting the method to call, a string to be evaluated, " +
189
+ "a block to be invoked, or an object responding to the callback method."
190
+ end
191
+ end
192
+ end
193
+
194
+ def should_run_callback?(*args)
195
+ if options[:if]
196
+ evaluate_method(options[:if], *args)
197
+ elsif options[:unless]
198
+ !evaluate_method(options[:unless], *args)
199
+ else
200
+ true
201
+ end
202
+ end
203
+ end
204
+
205
+ def self.included(base)
206
+ base.extend ClassMethods
207
+ end
208
+
209
+ module ClassMethods
210
+ def define_callbacks(*callbacks)
211
+ callbacks.each do |callback|
212
+ class_eval <<-"end_eval"
213
+ def self.#{callback}(*methods, &block)
214
+ callbacks = CallbackChain.build(:#{callback}, *methods, &block)
215
+ (@#{callback}_callbacks ||= CallbackChain.new).concat callbacks
216
+ end
217
+
218
+ def self.#{callback}_callback_chain
219
+ @#{callback}_callbacks ||= CallbackChain.new
220
+
221
+ if superclass.respond_to?(:#{callback}_callback_chain)
222
+ CallbackChain.new(superclass.#{callback}_callback_chain + @#{callback}_callbacks)
223
+ else
224
+ @#{callback}_callbacks
225
+ end
226
+ end
227
+ end_eval
228
+ end
229
+ end
230
+ end
231
+
232
+ # Runs all the callbacks defined for the given options.
233
+ #
234
+ # If a block is given it will be called after each callback receiving as arguments:
235
+ #
236
+ # * the result from the callback
237
+ # * the object which has the callback
238
+ #
239
+ # If the result from the block evaluates to false, the callback chain is stopped.
240
+ #
241
+ # Example:
242
+ # class Storage
243
+ # include ActiveSupport::Callbacks
244
+ #
245
+ # define_callbacks :before_save, :after_save
246
+ # end
247
+ #
248
+ # class ConfigStorage < Storage
249
+ # before_save :pass
250
+ # before_save :pass
251
+ # before_save :stop
252
+ # before_save :pass
253
+ #
254
+ # def pass
255
+ # puts "pass"
256
+ # end
257
+ #
258
+ # def stop
259
+ # puts "stop"
260
+ # return false
261
+ # end
262
+ #
263
+ # def save
264
+ # result = run_callbacks(:before_save) { |result, object| result == false }
265
+ # puts "- save" if result
266
+ # end
267
+ # end
268
+ #
269
+ # config = ConfigStorage.new
270
+ # config.save
271
+ #
272
+ # Output:
273
+ # pass
274
+ # pass
275
+ # stop
276
+ def run_callbacks(kind, options = {}, &block)
277
+ self.class.send("#{kind}_callback_chain").run(self, options, &block)
278
+ end
279
+ end
280
+ end