csd 0.1.5 → 0.1.6
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/COPYING +1 -2
- data/README.rdoc +7 -1
- data/Rakefile +7 -2
- data/VERSION +1 -1
- data/csd.gemspec +18 -216
- data/lib/csd.rb +6 -16
- data/lib/csd/application.rb +2 -2
- data/lib/csd/application/default.rb +15 -14
- data/lib/csd/application/default/base.rb +1 -1
- data/lib/csd/application/minisip.rb +43 -11
- data/lib/csd/application/minisip/about.yml +5 -5
- data/lib/csd/application/minisip/base.rb +82 -70
- data/lib/csd/application/minisip/error.rb +1 -1
- data/lib/csd/application/minisip/options/common.rb +1 -1
- data/lib/csd/application/minisip/options/compile.rb +1 -1
- data/lib/csd/application/minisip/options/package.rb +1 -1
- data/lib/csd/application/minisip/unix.rb +40 -27
- data/lib/csd/application/minisip/unix/darwin.rb +12 -0
- data/lib/csd/application/minisip/unix/linux.rb +1 -11
- data/lib/csd/application/minisip/unix/linux/debian.rb +14 -25
- data/lib/csd/application/minisip/unix/linux/debian/ubuntu10.rb +12 -13
- data/lib/csd/applications.rb +5 -5
- data/lib/csd/commands.rb +164 -89
- data/lib/csd/container.rb +61 -0
- data/lib/csd/error.rb +10 -1
- data/lib/csd/extensions.rb +3 -2
- data/lib/csd/extensions/core/array.rb +29 -1
- data/lib/csd/extensions/core/dir.rb +15 -24
- data/lib/csd/extensions/core/object.rb +10 -2
- data/lib/csd/extensions/core/option_parser.rb +22 -3
- data/lib/csd/extensions/core/pathname.rb +30 -2
- data/lib/csd/extensions/core/string.rb +51 -4
- data/lib/csd/extensions/gem/platform.rb +18 -3
- data/lib/csd/{options.rb → options_parser.rb} +16 -20
- data/lib/csd/path_container.rb +24 -0
- data/lib/csd/user_interface.rb +2 -0
- data/lib/csd/user_interface/base.rb +26 -0
- data/lib/csd/user_interface/cli.rb +37 -0
- data/lib/csd/vendor/active_support/MIT-LICENSE +20 -0
- data/lib/csd/vendor/active_support/inflector.rb +155 -0
- data/lib/csd/vendor/term/GPL2-LICENSE +339 -0
- data/lib/csd/vendor/term/ansicolor.rb +113 -0
- data/lib/csd/version.rb +13 -4
- data/test/application/test_minisip.rb +45 -0
- data/test/functional/test_applications.rb +10 -16
- data/test/functional/test_commands.rb +260 -23
- data/test/unit/test_string.rb +1 -1
- metadata +18 -216
- data/lib/active_support.rb +0 -75
- data/lib/active_support/all.rb +0 -3
- data/lib/active_support/backtrace_cleaner.rb +0 -94
- data/lib/active_support/base64.rb +0 -42
- data/lib/active_support/basic_object.rb +0 -21
- data/lib/active_support/benchmarkable.rb +0 -60
- data/lib/active_support/buffered_logger.rb +0 -132
- data/lib/active_support/builder.rb +0 -6
- data/lib/active_support/cache.rb +0 -626
- data/lib/active_support/cache/compressed_mem_cache_store.rb +0 -13
- data/lib/active_support/cache/file_store.rb +0 -188
- data/lib/active_support/cache/mem_cache_store.rb +0 -191
- data/lib/active_support/cache/memory_store.rb +0 -159
- data/lib/active_support/cache/strategy/local_cache.rb +0 -164
- data/lib/active_support/cache/synchronized_memory_store.rb +0 -11
- data/lib/active_support/callbacks.rb +0 -600
- data/lib/active_support/concern.rb +0 -29
- data/lib/active_support/configurable.rb +0 -36
- data/lib/active_support/core_ext.rb +0 -3
- data/lib/active_support/core_ext/array.rb +0 -7
- data/lib/active_support/core_ext/array/access.rb +0 -46
- data/lib/active_support/core_ext/array/conversions.rb +0 -164
- data/lib/active_support/core_ext/array/extract_options.rb +0 -29
- data/lib/active_support/core_ext/array/grouping.rb +0 -100
- data/lib/active_support/core_ext/array/random_access.rb +0 -20
- data/lib/active_support/core_ext/array/uniq_by.rb +0 -17
- data/lib/active_support/core_ext/array/wrap.rb +0 -22
- data/lib/active_support/core_ext/benchmark.rb +0 -7
- data/lib/active_support/core_ext/big_decimal.rb +0 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +0 -27
- data/lib/active_support/core_ext/cgi.rb +0 -1
- data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -19
- data/lib/active_support/core_ext/class.rb +0 -4
- data/lib/active_support/core_ext/class/attribute.rb +0 -67
- data/lib/active_support/core_ext/class/attribute_accessors.rb +0 -63
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -44
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +0 -232
- data/lib/active_support/core_ext/class/subclasses.rb +0 -55
- data/lib/active_support/core_ext/date/acts_like.rb +0 -8
- data/lib/active_support/core_ext/date/calculations.rb +0 -240
- data/lib/active_support/core_ext/date/conversions.rb +0 -99
- data/lib/active_support/core_ext/date/freeze.rb +0 -31
- data/lib/active_support/core_ext/date_time/acts_like.rb +0 -13
- data/lib/active_support/core_ext/date_time/calculations.rb +0 -113
- data/lib/active_support/core_ext/date_time/conversions.rb +0 -102
- data/lib/active_support/core_ext/date_time/zones.rb +0 -17
- data/lib/active_support/core_ext/enumerable.rb +0 -119
- data/lib/active_support/core_ext/exception.rb +0 -3
- data/lib/active_support/core_ext/file.rb +0 -2
- data/lib/active_support/core_ext/file/atomic.rb +0 -41
- data/lib/active_support/core_ext/file/path.rb +0 -5
- data/lib/active_support/core_ext/float.rb +0 -1
- data/lib/active_support/core_ext/float/rounding.rb +0 -19
- data/lib/active_support/core_ext/hash.rb +0 -8
- data/lib/active_support/core_ext/hash/conversions.rb +0 -150
- data/lib/active_support/core_ext/hash/deep_merge.rb +0 -16
- data/lib/active_support/core_ext/hash/diff.rb +0 -13
- data/lib/active_support/core_ext/hash/except.rb +0 -24
- data/lib/active_support/core_ext/hash/indifferent_access.rb +0 -14
- data/lib/active_support/core_ext/hash/keys.rb +0 -45
- data/lib/active_support/core_ext/hash/reverse_merge.rb +0 -28
- data/lib/active_support/core_ext/hash/slice.rb +0 -38
- data/lib/active_support/core_ext/integer.rb +0 -3
- data/lib/active_support/core_ext/integer/inflections.rb +0 -14
- data/lib/active_support/core_ext/integer/multiple.rb +0 -6
- data/lib/active_support/core_ext/integer/time.rb +0 -39
- data/lib/active_support/core_ext/kernel.rb +0 -5
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -16
- data/lib/active_support/core_ext/kernel/reporting.rb +0 -62
- data/lib/active_support/core_ext/kernel/requires.rb +0 -26
- data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -13
- data/lib/active_support/core_ext/load_error.rb +0 -23
- data/lib/active_support/core_ext/logger.rb +0 -146
- data/lib/active_support/core_ext/module.rb +0 -12
- data/lib/active_support/core_ext/module/aliasing.rb +0 -70
- data/lib/active_support/core_ext/module/anonymous.rb +0 -24
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +0 -31
- data/lib/active_support/core_ext/module/attr_internal.rb +0 -32
- data/lib/active_support/core_ext/module/attribute_accessors.rb +0 -66
- data/lib/active_support/core_ext/module/delegation.rb +0 -146
- data/lib/active_support/core_ext/module/deprecation.rb +0 -9
- data/lib/active_support/core_ext/module/introspection.rb +0 -88
- data/lib/active_support/core_ext/module/method_names.rb +0 -14
- data/lib/active_support/core_ext/module/reachable.rb +0 -10
- data/lib/active_support/core_ext/module/remove_method.rb +0 -6
- data/lib/active_support/core_ext/module/synchronization.rb +0 -42
- data/lib/active_support/core_ext/name_error.rb +0 -18
- data/lib/active_support/core_ext/numeric.rb +0 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +0 -44
- data/lib/active_support/core_ext/numeric/time.rb +0 -77
- data/lib/active_support/core_ext/object.rb +0 -14
- data/lib/active_support/core_ext/object/acts_like.rb +0 -10
- data/lib/active_support/core_ext/object/blank.rb +0 -76
- data/lib/active_support/core_ext/object/conversions.rb +0 -4
- data/lib/active_support/core_ext/object/duplicable.rb +0 -65
- data/lib/active_support/core_ext/object/extending.rb +0 -11
- data/lib/active_support/core_ext/object/instance_variables.rb +0 -67
- data/lib/active_support/core_ext/object/misc.rb +0 -2
- data/lib/active_support/core_ext/object/returning.rb +0 -42
- data/lib/active_support/core_ext/object/to_param.rb +0 -49
- data/lib/active_support/core_ext/object/to_query.rb +0 -27
- data/lib/active_support/core_ext/object/try.rb +0 -36
- data/lib/active_support/core_ext/object/with_options.rb +0 -26
- data/lib/active_support/core_ext/proc.rb +0 -14
- data/lib/active_support/core_ext/process.rb +0 -1
- data/lib/active_support/core_ext/process/daemon.rb +0 -23
- data/lib/active_support/core_ext/range.rb +0 -4
- data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
- data/lib/active_support/core_ext/range/conversions.rb +0 -21
- data/lib/active_support/core_ext/range/include_range.rb +0 -21
- data/lib/active_support/core_ext/range/overlaps.rb +0 -8
- data/lib/active_support/core_ext/regexp.rb +0 -5
- data/lib/active_support/core_ext/rexml.rb +0 -46
- data/lib/active_support/core_ext/string.rb +0 -12
- data/lib/active_support/core_ext/string/access.rb +0 -99
- data/lib/active_support/core_ext/string/behavior.rb +0 -7
- data/lib/active_support/core_ext/string/conversions.rb +0 -61
- data/lib/active_support/core_ext/string/encoding.rb +0 -11
- data/lib/active_support/core_ext/string/exclude.rb +0 -6
- data/lib/active_support/core_ext/string/filters.rb +0 -49
- data/lib/active_support/core_ext/string/inflections.rb +0 -149
- data/lib/active_support/core_ext/string/interpolation.rb +0 -2
- data/lib/active_support/core_ext/string/multibyte.rb +0 -72
- data/lib/active_support/core_ext/string/output_safety.rb +0 -109
- data/lib/active_support/core_ext/string/starts_ends_with.rb +0 -4
- data/lib/active_support/core_ext/string/xchar.rb +0 -18
- data/lib/active_support/core_ext/time/acts_like.rb +0 -8
- data/lib/active_support/core_ext/time/calculations.rb +0 -282
- data/lib/active_support/core_ext/time/conversions.rb +0 -85
- data/lib/active_support/core_ext/time/marshal.rb +0 -56
- data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
- data/lib/active_support/core_ext/time/zones.rb +0 -78
- data/lib/active_support/core_ext/uri.rb +0 -22
- data/lib/active_support/dependencies.rb +0 -628
- data/lib/active_support/dependencies/autoload.rb +0 -50
- data/lib/active_support/deprecation.rb +0 -18
- data/lib/active_support/deprecation/behaviors.rb +0 -38
- data/lib/active_support/deprecation/method_wrappers.rb +0 -29
- data/lib/active_support/deprecation/proxy_wrappers.rb +0 -74
- data/lib/active_support/deprecation/reporting.rb +0 -56
- data/lib/active_support/duration.rb +0 -105
- data/lib/active_support/gzip.rb +0 -25
- data/lib/active_support/hash_with_indifferent_access.rb +0 -145
- data/lib/active_support/i18n.rb +0 -8
- data/lib/active_support/inflections.rb +0 -56
- data/lib/active_support/inflector.rb +0 -7
- data/lib/active_support/inflector/inflections.rb +0 -211
- data/lib/active_support/inflector/methods.rb +0 -141
- data/lib/active_support/inflector/transliterate.rb +0 -97
- data/lib/active_support/json.rb +0 -2
- data/lib/active_support/json/backends/jsongem.rb +0 -43
- data/lib/active_support/json/backends/yajl.rb +0 -40
- data/lib/active_support/json/backends/yaml.rb +0 -90
- data/lib/active_support/json/decoding.rb +0 -51
- data/lib/active_support/json/encoding.rb +0 -254
- data/lib/active_support/json/variable.rb +0 -11
- data/lib/active_support/lazy_load_hooks.rb +0 -27
- data/lib/active_support/locale/en.yml +0 -36
- data/lib/active_support/memoizable.rb +0 -103
- data/lib/active_support/message_encryptor.rb +0 -71
- data/lib/active_support/message_verifier.rb +0 -62
- data/lib/active_support/multibyte.rb +0 -44
- data/lib/active_support/multibyte/chars.rb +0 -480
- data/lib/active_support/multibyte/exceptions.rb +0 -8
- data/lib/active_support/multibyte/unicode.rb +0 -393
- data/lib/active_support/multibyte/utils.rb +0 -60
- data/lib/active_support/notifications.rb +0 -81
- data/lib/active_support/notifications/fanout.rb +0 -93
- data/lib/active_support/notifications/instrumenter.rb +0 -56
- data/lib/active_support/option_merger.rb +0 -25
- data/lib/active_support/ordered_hash.rb +0 -158
- data/lib/active_support/ordered_options.rb +0 -27
- data/lib/active_support/railtie.rb +0 -100
- data/lib/active_support/rescuable.rb +0 -114
- data/lib/active_support/ruby/shim.rb +0 -22
- data/lib/active_support/secure_random.rb +0 -199
- data/lib/active_support/string_inquirer.rb +0 -21
- data/lib/active_support/test_case.rb +0 -42
- data/lib/active_support/testing/assertions.rb +0 -82
- data/lib/active_support/testing/declarative.rb +0 -40
- data/lib/active_support/testing/default.rb +0 -9
- data/lib/active_support/testing/deprecation.rb +0 -55
- data/lib/active_support/testing/isolation.rb +0 -154
- data/lib/active_support/testing/pending.rb +0 -48
- data/lib/active_support/testing/performance.rb +0 -455
- data/lib/active_support/testing/setup_and_teardown.rb +0 -111
- data/lib/active_support/time.rb +0 -34
- data/lib/active_support/time/autoload.rb +0 -5
- data/lib/active_support/time_with_zone.rb +0 -341
- data/lib/active_support/values/time_zone.rb +0 -377
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +0 -10
- data/lib/active_support/whiny_nil.rb +0 -60
- data/lib/active_support/xml_mini.rb +0 -158
- data/lib/active_support/xml_mini/jdom.rb +0 -168
- data/lib/active_support/xml_mini/libxml.rb +0 -80
- data/lib/active_support/xml_mini/libxmlsax.rb +0 -85
- data/lib/active_support/xml_mini/nokogiri.rb +0 -78
- data/lib/active_support/xml_mini/nokogirisax.rb +0 -83
- data/lib/active_support/xml_mini/rexml.rb +0 -129
- data/lib/csd/extensions/core/file.rb +0 -14
- data/lib/csd/global_open_struct.rb +0 -19
- data/lib/csd/path.rb +0 -32
- data/lib/csd/ui.rb +0 -2
- data/lib/csd/ui/cli.rb +0 -8
- data/lib/csd/ui/ui.rb +0 -45
- data/lib/term/ansicolor.rb +0 -102
- data/lib/term/ansicolor/.keep +0 -0
- data/lib/term/ansicolor/version.rb +0 -10
@@ -1,164 +0,0 @@
|
|
1
|
-
require 'active_support/core_ext/object/duplicable'
|
2
|
-
require 'active_support/core_ext/string/inflections'
|
3
|
-
|
4
|
-
module ActiveSupport
|
5
|
-
module Cache
|
6
|
-
module Strategy
|
7
|
-
# Caches that implement LocalCache will be backed by an in memory cache for the
|
8
|
-
# duration of a block. Repeated calls to the cache for the same key will hit the
|
9
|
-
# in memory cache for faster access.
|
10
|
-
module LocalCache
|
11
|
-
# Simple memory backed cache. This cache is not thread safe but is intended only
|
12
|
-
# for serving as a temporary memory cache for a single thread.
|
13
|
-
class LocalStore < Store
|
14
|
-
def initialize
|
15
|
-
super
|
16
|
-
@data = {}
|
17
|
-
end
|
18
|
-
|
19
|
-
# Since it isn't thread safe, don't allow synchronizing.
|
20
|
-
def synchronize # :nodoc:
|
21
|
-
yield
|
22
|
-
end
|
23
|
-
|
24
|
-
def clear(options = nil)
|
25
|
-
@data.clear
|
26
|
-
end
|
27
|
-
|
28
|
-
def read_entry(key, options)
|
29
|
-
@data[key]
|
30
|
-
end
|
31
|
-
|
32
|
-
def write_entry(key, value, options)
|
33
|
-
@data[key] = value
|
34
|
-
true
|
35
|
-
end
|
36
|
-
|
37
|
-
def delete_entry(key, options)
|
38
|
-
!!@data.delete(key)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# Use a local cache to front for the cache for the duration of a block.
|
43
|
-
def with_local_cache
|
44
|
-
save_val = Thread.current[thread_local_key]
|
45
|
-
begin
|
46
|
-
Thread.current[thread_local_key] = LocalStore.new
|
47
|
-
yield
|
48
|
-
ensure
|
49
|
-
Thread.current[thread_local_key] = save_val
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# Middleware class can be inserted as a Rack handler to use a local cache for the
|
54
|
-
# duration of a request.
|
55
|
-
def middleware
|
56
|
-
@middleware ||= begin
|
57
|
-
klass = Class.new
|
58
|
-
klass.class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
59
|
-
class << self
|
60
|
-
def name
|
61
|
-
"ActiveSupport::Cache::Strategy::LocalCache"
|
62
|
-
end
|
63
|
-
alias :to_s :name
|
64
|
-
end
|
65
|
-
|
66
|
-
def initialize(app)
|
67
|
-
@app = app
|
68
|
-
end
|
69
|
-
|
70
|
-
def call(env)
|
71
|
-
Thread.current[:#{thread_local_key}] = LocalStore.new
|
72
|
-
@app.call(env)
|
73
|
-
ensure
|
74
|
-
Thread.current[:#{thread_local_key}] = nil
|
75
|
-
end
|
76
|
-
EOS
|
77
|
-
klass
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def clear(options = nil) # :nodoc:
|
82
|
-
local_cache.clear(options) if local_cache
|
83
|
-
super
|
84
|
-
end
|
85
|
-
|
86
|
-
def cleanup(options = nil) # :nodoc:
|
87
|
-
local_cache.clear(options) if local_cache
|
88
|
-
super
|
89
|
-
end
|
90
|
-
|
91
|
-
def increment(name, amount = 1, options = nil) # :nodoc:
|
92
|
-
value = bypass_local_cache{super}
|
93
|
-
if local_cache
|
94
|
-
local_cache.mute do
|
95
|
-
if value
|
96
|
-
local_cache.write(name, value, options)
|
97
|
-
else
|
98
|
-
local_cache.delete(name, options)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
value
|
103
|
-
end
|
104
|
-
|
105
|
-
def decrement(name, amount = 1, options = nil) # :nodoc:
|
106
|
-
value = bypass_local_cache{super}
|
107
|
-
if local_cache
|
108
|
-
local_cache.mute do
|
109
|
-
if value
|
110
|
-
local_cache.write(name, value, options)
|
111
|
-
else
|
112
|
-
local_cache.delete(name, options)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
value
|
117
|
-
end
|
118
|
-
|
119
|
-
protected
|
120
|
-
def read_entry(key, options) # :nodoc:
|
121
|
-
if local_cache
|
122
|
-
entry = local_cache.read_entry(key, options)
|
123
|
-
unless entry
|
124
|
-
entry = super
|
125
|
-
local_cache.write_entry(key, entry, options)
|
126
|
-
end
|
127
|
-
entry
|
128
|
-
else
|
129
|
-
super
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
def write_entry(key, entry, options) # :nodoc:
|
134
|
-
local_cache.write_entry(key, entry, options) if local_cache
|
135
|
-
super
|
136
|
-
end
|
137
|
-
|
138
|
-
def delete_entry(key, options) # :nodoc:
|
139
|
-
local_cache.delete_entry(key, options) if local_cache
|
140
|
-
super
|
141
|
-
end
|
142
|
-
|
143
|
-
private
|
144
|
-
def thread_local_key
|
145
|
-
@thread_local_key ||= "#{self.class.name.underscore}_local_cache_#{object_id}".gsub(/[\/-]/, '_').to_sym
|
146
|
-
end
|
147
|
-
|
148
|
-
def local_cache
|
149
|
-
Thread.current[thread_local_key]
|
150
|
-
end
|
151
|
-
|
152
|
-
def bypass_local_cache
|
153
|
-
save_cache = Thread.current[thread_local_key]
|
154
|
-
begin
|
155
|
-
Thread.current[thread_local_key] = nil
|
156
|
-
yield
|
157
|
-
ensure
|
158
|
-
Thread.current[thread_local_key] = save_cache
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
@@ -1,11 +0,0 @@
|
|
1
|
-
module ActiveSupport
|
2
|
-
module Cache
|
3
|
-
# Like MemoryStore, but thread-safe.
|
4
|
-
class SynchronizedMemoryStore < MemoryStore
|
5
|
-
def initialize(*args)
|
6
|
-
ActiveSupport::Deprecation.warn('ActiveSupport::Cache::SynchronizedMemoryStore has been deprecated in favor of ActiveSupport::Cache::MemoryStore.', caller)
|
7
|
-
super
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
@@ -1,600 +0,0 @@
|
|
1
|
-
require 'active_support/core_ext/array/wrap'
|
2
|
-
require 'active_support/core_ext/class/inheritable_attributes'
|
3
|
-
require 'active_support/core_ext/kernel/reporting'
|
4
|
-
require 'active_support/core_ext/kernel/singleton_class'
|
5
|
-
|
6
|
-
module ActiveSupport
|
7
|
-
# Callbacks are hooks into the lifecycle of an object that allow you to trigger logic
|
8
|
-
# before or after an alteration of the object state.
|
9
|
-
#
|
10
|
-
# Mixing in this module allows you to define callbacks in your class.
|
11
|
-
#
|
12
|
-
# Example:
|
13
|
-
# class Storage
|
14
|
-
# include ActiveSupport::Callbacks
|
15
|
-
#
|
16
|
-
# define_callbacks :save
|
17
|
-
# end
|
18
|
-
#
|
19
|
-
# class ConfigStorage < Storage
|
20
|
-
# set_callback :save, :before, :saving_message
|
21
|
-
# def saving_message
|
22
|
-
# puts "saving..."
|
23
|
-
# end
|
24
|
-
#
|
25
|
-
# set_callback :save, :after do |object|
|
26
|
-
# puts "saved"
|
27
|
-
# end
|
28
|
-
#
|
29
|
-
# def save
|
30
|
-
# run_callbacks :save do
|
31
|
-
# puts "- save"
|
32
|
-
# end
|
33
|
-
# end
|
34
|
-
# end
|
35
|
-
#
|
36
|
-
# config = ConfigStorage.new
|
37
|
-
# config.save
|
38
|
-
#
|
39
|
-
# Output:
|
40
|
-
# saving...
|
41
|
-
# - save
|
42
|
-
# saved
|
43
|
-
#
|
44
|
-
# Callbacks from parent classes are inherited.
|
45
|
-
#
|
46
|
-
# Example:
|
47
|
-
# class Storage
|
48
|
-
# include ActiveSupport::Callbacks
|
49
|
-
#
|
50
|
-
# define_callbacks :save
|
51
|
-
#
|
52
|
-
# set_callback :save, :before, :prepare
|
53
|
-
# def prepare
|
54
|
-
# puts "preparing save"
|
55
|
-
# end
|
56
|
-
# end
|
57
|
-
#
|
58
|
-
# class ConfigStorage < Storage
|
59
|
-
# set_callback :save, :before, :saving_message
|
60
|
-
# def saving_message
|
61
|
-
# puts "saving..."
|
62
|
-
# end
|
63
|
-
#
|
64
|
-
# set_callback :save, :after do |object|
|
65
|
-
# puts "saved"
|
66
|
-
# end
|
67
|
-
#
|
68
|
-
# def save
|
69
|
-
# run_callbacks :save do
|
70
|
-
# puts "- save"
|
71
|
-
# end
|
72
|
-
# end
|
73
|
-
# end
|
74
|
-
#
|
75
|
-
# config = ConfigStorage.new
|
76
|
-
# config.save
|
77
|
-
#
|
78
|
-
# Output:
|
79
|
-
# preparing save
|
80
|
-
# saving...
|
81
|
-
# - save
|
82
|
-
# saved
|
83
|
-
#
|
84
|
-
module Callbacks
|
85
|
-
extend Concern
|
86
|
-
|
87
|
-
def run_callbacks(kind, *args, &block)
|
88
|
-
send("_run_#{kind}_callbacks", *args, &block)
|
89
|
-
end
|
90
|
-
|
91
|
-
class Callback
|
92
|
-
@@_callback_sequence = 0
|
93
|
-
|
94
|
-
attr_accessor :chain, :filter, :kind, :options, :per_key, :klass, :raw_filter
|
95
|
-
|
96
|
-
def initialize(chain, filter, kind, options, klass)
|
97
|
-
@chain, @kind, @klass = chain, kind, klass
|
98
|
-
normalize_options!(options)
|
99
|
-
|
100
|
-
@per_key = options.delete(:per_key)
|
101
|
-
@raw_filter, @options = filter, options
|
102
|
-
@filter = _compile_filter(filter)
|
103
|
-
@compiled_options = _compile_options(options)
|
104
|
-
@callback_id = next_id
|
105
|
-
|
106
|
-
_compile_per_key_options
|
107
|
-
end
|
108
|
-
|
109
|
-
def clone(chain, klass)
|
110
|
-
obj = super()
|
111
|
-
obj.chain = chain
|
112
|
-
obj.klass = klass
|
113
|
-
obj.per_key = @per_key.dup
|
114
|
-
obj.options = @options.dup
|
115
|
-
obj.per_key[:if] = @per_key[:if].dup
|
116
|
-
obj.per_key[:unless] = @per_key[:unless].dup
|
117
|
-
obj.options[:if] = @options[:if].dup
|
118
|
-
obj.options[:unless] = @options[:unless].dup
|
119
|
-
obj
|
120
|
-
end
|
121
|
-
|
122
|
-
def normalize_options!(options)
|
123
|
-
options[:if] = Array.wrap(options[:if])
|
124
|
-
options[:unless] = Array.wrap(options[:unless])
|
125
|
-
|
126
|
-
options[:per_key] ||= {}
|
127
|
-
options[:per_key][:if] = Array.wrap(options[:per_key][:if])
|
128
|
-
options[:per_key][:unless] = Array.wrap(options[:per_key][:unless])
|
129
|
-
end
|
130
|
-
|
131
|
-
def name
|
132
|
-
chain.name
|
133
|
-
end
|
134
|
-
|
135
|
-
def next_id
|
136
|
-
@@_callback_sequence += 1
|
137
|
-
end
|
138
|
-
|
139
|
-
def matches?(_kind, _filter)
|
140
|
-
@kind == _kind && @filter == _filter
|
141
|
-
end
|
142
|
-
|
143
|
-
def _update_filter(filter_options, new_options)
|
144
|
-
filter_options[:if].push(new_options[:unless]) if new_options.key?(:unless)
|
145
|
-
filter_options[:unless].push(new_options[:if]) if new_options.key?(:if)
|
146
|
-
end
|
147
|
-
|
148
|
-
def recompile!(_options, _per_key)
|
149
|
-
_update_filter(self.options, _options)
|
150
|
-
_update_filter(self.per_key, _per_key)
|
151
|
-
|
152
|
-
@callback_id = next_id
|
153
|
-
@filter = _compile_filter(@raw_filter)
|
154
|
-
@compiled_options = _compile_options(@options)
|
155
|
-
_compile_per_key_options
|
156
|
-
end
|
157
|
-
|
158
|
-
def _compile_per_key_options
|
159
|
-
key_options = _compile_options(@per_key)
|
160
|
-
|
161
|
-
@klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
162
|
-
def _one_time_conditions_valid_#{@callback_id}?
|
163
|
-
true #{key_options[0]}
|
164
|
-
end
|
165
|
-
RUBY_EVAL
|
166
|
-
end
|
167
|
-
|
168
|
-
# This will supply contents for before and around filters, and no
|
169
|
-
# contents for after filters (for the forward pass).
|
170
|
-
def start(key=nil, object=nil)
|
171
|
-
return if key && !object.send("_one_time_conditions_valid_#{@callback_id}?")
|
172
|
-
|
173
|
-
# options[0] is the compiled form of supplied conditions
|
174
|
-
# options[1] is the "end" for the conditional
|
175
|
-
#
|
176
|
-
if @kind == :before || @kind == :around
|
177
|
-
if @kind == :before
|
178
|
-
# if condition # before_save :filter_name, :if => :condition
|
179
|
-
# filter_name
|
180
|
-
# end
|
181
|
-
filter = <<-RUBY_EVAL
|
182
|
-
unless halted
|
183
|
-
result = #{@filter}
|
184
|
-
halted = (#{chain.config[:terminator]})
|
185
|
-
end
|
186
|
-
RUBY_EVAL
|
187
|
-
|
188
|
-
[@compiled_options[0], filter, @compiled_options[1]].compact.join("\n")
|
189
|
-
else
|
190
|
-
# Compile around filters with conditions into proxy methods
|
191
|
-
# that contain the conditions.
|
192
|
-
#
|
193
|
-
# For `around_save :filter_name, :if => :condition':
|
194
|
-
#
|
195
|
-
# def _conditional_callback_save_17
|
196
|
-
# if condition
|
197
|
-
# filter_name do
|
198
|
-
# yield self
|
199
|
-
# end
|
200
|
-
# else
|
201
|
-
# yield self
|
202
|
-
# end
|
203
|
-
# end
|
204
|
-
#
|
205
|
-
name = "_conditional_callback_#{@kind}_#{next_id}"
|
206
|
-
@klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
207
|
-
def #{name}(halted)
|
208
|
-
#{@compiled_options[0] || "if true"} && !halted
|
209
|
-
#{@filter} do
|
210
|
-
yield self
|
211
|
-
end
|
212
|
-
else
|
213
|
-
yield self
|
214
|
-
end
|
215
|
-
end
|
216
|
-
RUBY_EVAL
|
217
|
-
"#{name}(halted) do"
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
# This will supply contents for around and after filters, but not
|
223
|
-
# before filters (for the backward pass).
|
224
|
-
def end(key=nil, object=nil)
|
225
|
-
return if key && !object.send("_one_time_conditions_valid_#{@callback_id}?")
|
226
|
-
|
227
|
-
if @kind == :around || @kind == :after
|
228
|
-
# if condition # after_save :filter_name, :if => :condition
|
229
|
-
# filter_name
|
230
|
-
# end
|
231
|
-
if @kind == :after
|
232
|
-
[@compiled_options[0], @filter, @compiled_options[1]].compact.join("\n")
|
233
|
-
else
|
234
|
-
"end"
|
235
|
-
end
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
private
|
240
|
-
|
241
|
-
# Options support the same options as filters themselves (and support
|
242
|
-
# symbols, string, procs, and objects), so compile a conditional
|
243
|
-
# expression based on the options
|
244
|
-
def _compile_options(options)
|
245
|
-
return [] if options[:if].empty? && options[:unless].empty?
|
246
|
-
|
247
|
-
conditions = []
|
248
|
-
|
249
|
-
unless options[:if].empty?
|
250
|
-
conditions << Array.wrap(_compile_filter(options[:if]))
|
251
|
-
end
|
252
|
-
|
253
|
-
unless options[:unless].empty?
|
254
|
-
conditions << Array.wrap(_compile_filter(options[:unless])).map {|f| "!#{f}"}
|
255
|
-
end
|
256
|
-
|
257
|
-
["if #{conditions.flatten.join(" && ")}", "end"]
|
258
|
-
end
|
259
|
-
|
260
|
-
# Filters support:
|
261
|
-
#
|
262
|
-
# Arrays:: Used in conditions. This is used to specify
|
263
|
-
# multiple conditions. Used internally to
|
264
|
-
# merge conditions from skip_* filters
|
265
|
-
# Symbols:: A method to call
|
266
|
-
# Strings:: Some content to evaluate
|
267
|
-
# Procs:: A proc to call with the object
|
268
|
-
# Objects:: An object with a before_foo method on it to call
|
269
|
-
#
|
270
|
-
# All of these objects are compiled into methods and handled
|
271
|
-
# the same after this point:
|
272
|
-
#
|
273
|
-
# Arrays:: Merged together into a single filter
|
274
|
-
# Symbols:: Already methods
|
275
|
-
# Strings:: class_eval'ed into methods
|
276
|
-
# Procs:: define_method'ed into methods
|
277
|
-
# Objects::
|
278
|
-
# a method is created that calls the before_foo method
|
279
|
-
# on the object.
|
280
|
-
#
|
281
|
-
def _compile_filter(filter)
|
282
|
-
method_name = "_callback_#{@kind}_#{next_id}"
|
283
|
-
case filter
|
284
|
-
when Array
|
285
|
-
filter.map {|f| _compile_filter(f)}
|
286
|
-
when Symbol
|
287
|
-
filter
|
288
|
-
when String
|
289
|
-
"(#{filter})"
|
290
|
-
when Proc
|
291
|
-
@klass.send(:define_method, method_name, &filter)
|
292
|
-
return method_name if filter.arity <= 0
|
293
|
-
|
294
|
-
method_name << (filter.arity == 1 ? "(self)" : " self, Proc.new ")
|
295
|
-
else
|
296
|
-
@klass.send(:define_method, "#{method_name}_object") { filter }
|
297
|
-
|
298
|
-
_normalize_legacy_filter(kind, filter)
|
299
|
-
scopes = Array.wrap(chain.config[:scope])
|
300
|
-
method_to_call = scopes.map{ |s| s.is_a?(Symbol) ? send(s) : s }.join("_")
|
301
|
-
|
302
|
-
@klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
303
|
-
def #{method_name}(&blk)
|
304
|
-
#{method_name}_object.send(:#{method_to_call}, self, &blk)
|
305
|
-
end
|
306
|
-
RUBY_EVAL
|
307
|
-
|
308
|
-
method_name
|
309
|
-
end
|
310
|
-
end
|
311
|
-
|
312
|
-
def _normalize_legacy_filter(kind, filter)
|
313
|
-
if !filter.respond_to?(kind) && filter.respond_to?(:filter)
|
314
|
-
filter.singleton_class.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
315
|
-
def #{kind}(context, &block) filter(context, &block) end
|
316
|
-
RUBY_EVAL
|
317
|
-
elsif filter.respond_to?(:before) && filter.respond_to?(:after) && kind == :around
|
318
|
-
def filter.around(context)
|
319
|
-
should_continue = before(context)
|
320
|
-
yield if should_continue
|
321
|
-
after(context)
|
322
|
-
end
|
323
|
-
end
|
324
|
-
end
|
325
|
-
end
|
326
|
-
|
327
|
-
# An Array with a compile method
|
328
|
-
class CallbackChain < Array
|
329
|
-
attr_reader :name, :config
|
330
|
-
|
331
|
-
def initialize(name, config)
|
332
|
-
@name = name
|
333
|
-
@config = {
|
334
|
-
:terminator => "false",
|
335
|
-
:rescuable => false,
|
336
|
-
:scope => [ :kind ]
|
337
|
-
}.merge(config)
|
338
|
-
end
|
339
|
-
|
340
|
-
def compile(key=nil, object=nil)
|
341
|
-
method = []
|
342
|
-
method << "value = nil"
|
343
|
-
method << "halted = false"
|
344
|
-
|
345
|
-
each do |callback|
|
346
|
-
method << callback.start(key, object)
|
347
|
-
end
|
348
|
-
|
349
|
-
if config[:rescuable]
|
350
|
-
method << "rescued_error = nil"
|
351
|
-
method << "begin"
|
352
|
-
end
|
353
|
-
|
354
|
-
method << "value = yield if block_given? && !halted"
|
355
|
-
|
356
|
-
if config[:rescuable]
|
357
|
-
method << "rescue Exception => e"
|
358
|
-
method << "rescued_error = e"
|
359
|
-
method << "end"
|
360
|
-
end
|
361
|
-
|
362
|
-
reverse_each do |callback|
|
363
|
-
method << callback.end(key, object)
|
364
|
-
end
|
365
|
-
|
366
|
-
method << "raise rescued_error if rescued_error" if config[:rescuable]
|
367
|
-
method << "halted ? false : (block_given? ? value : true)"
|
368
|
-
method.compact.join("\n")
|
369
|
-
end
|
370
|
-
end
|
371
|
-
|
372
|
-
module ClassMethods
|
373
|
-
# Make the run_callbacks :save method. The generated method takes
|
374
|
-
# a block that it'll yield to. It'll call the before and around filters
|
375
|
-
# in order, yield the block, and then run the after filters.
|
376
|
-
#
|
377
|
-
# run_callbacks :save do
|
378
|
-
# save
|
379
|
-
# end
|
380
|
-
#
|
381
|
-
# The run_callbacks :save method can optionally take a key, which
|
382
|
-
# will be used to compile an optimized callback method for each
|
383
|
-
# key. See #define_callbacks for more information.
|
384
|
-
#
|
385
|
-
def __define_runner(symbol) #:nodoc:
|
386
|
-
send("_update_#{symbol}_superclass_callbacks")
|
387
|
-
body = send("_#{symbol}_callbacks").compile(nil)
|
388
|
-
|
389
|
-
silence_warnings do
|
390
|
-
undef_method "_run_#{symbol}_callbacks" if method_defined?("_run_#{symbol}_callbacks")
|
391
|
-
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
392
|
-
def _run_#{symbol}_callbacks(key = nil, &blk)
|
393
|
-
@_initialized_#{symbol}_callbacks ||= begin
|
394
|
-
if self.class.send("_update_#{symbol}_superclass_callbacks")
|
395
|
-
self.class.__define_runner(#{symbol.inspect})
|
396
|
-
return _run_#{symbol}_callbacks(key, &blk)
|
397
|
-
end
|
398
|
-
true
|
399
|
-
end
|
400
|
-
|
401
|
-
if key
|
402
|
-
name = "_run__\#{self.class.name.hash.abs}__#{symbol}__\#{key.hash.abs}__callbacks"
|
403
|
-
|
404
|
-
unless respond_to?(name)
|
405
|
-
self.class.__create_keyed_callback(name, :#{symbol}, self, &blk)
|
406
|
-
end
|
407
|
-
|
408
|
-
send(name, &blk)
|
409
|
-
else
|
410
|
-
#{body}
|
411
|
-
end
|
412
|
-
end
|
413
|
-
private :_run_#{symbol}_callbacks
|
414
|
-
RUBY_EVAL
|
415
|
-
end
|
416
|
-
end
|
417
|
-
|
418
|
-
# This is called the first time a callback is called with a particular
|
419
|
-
# key. It creates a new callback method for the key, calculating
|
420
|
-
# which callbacks can be omitted because of per_key conditions.
|
421
|
-
#
|
422
|
-
def __create_keyed_callback(name, kind, object, &blk) #:nodoc:
|
423
|
-
@_keyed_callbacks ||= {}
|
424
|
-
@_keyed_callbacks[name] ||= begin
|
425
|
-
str = send("_#{kind}_callbacks").compile(name, object)
|
426
|
-
class_eval "def #{name}() #{str} end", __FILE__, __LINE__
|
427
|
-
true
|
428
|
-
end
|
429
|
-
end
|
430
|
-
|
431
|
-
# This is used internally to append, prepend and skip callbacks to the
|
432
|
-
# CallbackChain.
|
433
|
-
#
|
434
|
-
def __update_callbacks(name, filters = [], block = nil) #:nodoc:
|
435
|
-
send("_update_#{name}_superclass_callbacks")
|
436
|
-
|
437
|
-
type = [:before, :after, :around].include?(filters.first) ? filters.shift : :before
|
438
|
-
options = filters.last.is_a?(Hash) ? filters.pop : {}
|
439
|
-
filters.unshift(block) if block
|
440
|
-
|
441
|
-
chain = send("_#{name}_callbacks")
|
442
|
-
yield chain, type, filters, options if block_given?
|
443
|
-
|
444
|
-
__define_runner(name)
|
445
|
-
end
|
446
|
-
|
447
|
-
# Set callbacks for a previously defined callback.
|
448
|
-
#
|
449
|
-
# Syntax:
|
450
|
-
# set_callback :save, :before, :before_meth
|
451
|
-
# set_callback :save, :after, :after_meth, :if => :condition
|
452
|
-
# set_callback :save, :around, lambda { |r| stuff; yield; stuff }
|
453
|
-
#
|
454
|
-
# Use skip_callback to skip any defined one.
|
455
|
-
#
|
456
|
-
# When creating or skipping callbacks, you can specify conditions that
|
457
|
-
# are always the same for a given key. For instance, in ActionPack,
|
458
|
-
# we convert :only and :except conditions into per-key conditions.
|
459
|
-
#
|
460
|
-
# before_filter :authenticate, :except => "index"
|
461
|
-
# becomes
|
462
|
-
# dispatch_callback :before, :authenticate, :per_key => {:unless => proc {|c| c.action_name == "index"}}
|
463
|
-
#
|
464
|
-
# Per-Key conditions are evaluated only once per use of a given key.
|
465
|
-
# In the case of the above example, you would do:
|
466
|
-
#
|
467
|
-
# run_callbacks(:dispatch, action_name) { ... dispatch stuff ... }
|
468
|
-
#
|
469
|
-
# In that case, each action_name would get its own compiled callback
|
470
|
-
# method that took into consideration the per_key conditions. This
|
471
|
-
# is a speed improvement for ActionPack.
|
472
|
-
#
|
473
|
-
def set_callback(name, *filter_list, &block)
|
474
|
-
__update_callbacks(name, filter_list, block) do |chain, type, filters, options|
|
475
|
-
filters.map! do |filter|
|
476
|
-
removed = chain.delete_if {|c| c.matches?(type, filter) }
|
477
|
-
send("_removed_#{name}_callbacks").push(*removed)
|
478
|
-
Callback.new(chain, filter, type, options.dup, self)
|
479
|
-
end
|
480
|
-
|
481
|
-
options[:prepend] ? chain.unshift(*filters) : chain.push(*filters)
|
482
|
-
end
|
483
|
-
end
|
484
|
-
|
485
|
-
# Skip a previously defined callback for a given type.
|
486
|
-
#
|
487
|
-
def skip_callback(name, *filter_list, &block)
|
488
|
-
__update_callbacks(name, filter_list, block) do |chain, type, filters, options|
|
489
|
-
filters.each do |filter|
|
490
|
-
filter = chain.find {|c| c.matches?(type, filter) }
|
491
|
-
|
492
|
-
if filter && options.any?
|
493
|
-
new_filter = filter.clone(chain, self)
|
494
|
-
chain.insert(chain.index(filter), new_filter)
|
495
|
-
new_filter.recompile!(options, options[:per_key] || {})
|
496
|
-
end
|
497
|
-
|
498
|
-
chain.delete(filter)
|
499
|
-
send("_removed_#{name}_callbacks") << filter
|
500
|
-
end
|
501
|
-
end
|
502
|
-
end
|
503
|
-
|
504
|
-
# Reset callbacks for a given type.
|
505
|
-
#
|
506
|
-
def reset_callbacks(symbol)
|
507
|
-
callbacks = send("_#{symbol}_callbacks")
|
508
|
-
callbacks.clear
|
509
|
-
send("_removed_#{symbol}_callbacks").concat(callbacks)
|
510
|
-
__define_runner(symbol)
|
511
|
-
end
|
512
|
-
|
513
|
-
# Define callbacks types.
|
514
|
-
#
|
515
|
-
# ==== Example
|
516
|
-
#
|
517
|
-
# define_callbacks :validate
|
518
|
-
#
|
519
|
-
# ==== Options
|
520
|
-
#
|
521
|
-
# * <tt>:terminator</tt> - Indicates when a before filter is considered
|
522
|
-
# to be halted.
|
523
|
-
#
|
524
|
-
# define_callbacks :validate, :terminator => "result == false"
|
525
|
-
#
|
526
|
-
# In the example above, if any before validate callbacks returns false,
|
527
|
-
# other callbacks are not executed. Defaults to "false".
|
528
|
-
#
|
529
|
-
# * <tt>:rescuable</tt> - By default, after filters are not executed if
|
530
|
-
# the given block or an before_filter raises an error. Supply :rescuable => true
|
531
|
-
# to change this behavior.
|
532
|
-
#
|
533
|
-
# * <tt>:scope</tt> - Show which methods should be executed when a class
|
534
|
-
# is given as callback:
|
535
|
-
#
|
536
|
-
# define_callbacks :filters, :scope => [ :kind ]
|
537
|
-
#
|
538
|
-
# When a class is given:
|
539
|
-
#
|
540
|
-
# before_filter MyFilter
|
541
|
-
#
|
542
|
-
# It will call the type of the filter in the given class, which in this
|
543
|
-
# case, is "before".
|
544
|
-
#
|
545
|
-
# If, for instance, you supply the given scope:
|
546
|
-
#
|
547
|
-
# define_callbacks :validate, :scope => [ :kind, :name ]
|
548
|
-
#
|
549
|
-
# It will call "#{kind}_#{name}" in the given class. So "before_validate"
|
550
|
-
# will be called in the class below:
|
551
|
-
#
|
552
|
-
# before_validate MyValidation
|
553
|
-
#
|
554
|
-
# Defaults to :kind.
|
555
|
-
#
|
556
|
-
def define_callbacks(*callbacks)
|
557
|
-
config = callbacks.last.is_a?(Hash) ? callbacks.pop : {}
|
558
|
-
callbacks.each do |callback|
|
559
|
-
extlib_inheritable_reader("_#{callback}_callbacks") do
|
560
|
-
CallbackChain.new(callback, config)
|
561
|
-
end
|
562
|
-
|
563
|
-
extlib_inheritable_reader("_removed_#{callback}_callbacks") do
|
564
|
-
[]
|
565
|
-
end
|
566
|
-
|
567
|
-
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
568
|
-
def self._#{callback}_superclass_callbacks
|
569
|
-
if superclass.respond_to?(:_#{callback}_callbacks)
|
570
|
-
superclass._#{callback}_callbacks + superclass._#{callback}_superclass_callbacks
|
571
|
-
else
|
572
|
-
[]
|
573
|
-
end
|
574
|
-
end
|
575
|
-
|
576
|
-
def self._update_#{callback}_superclass_callbacks
|
577
|
-
changed, index = false, 0
|
578
|
-
|
579
|
-
callbacks = (_#{callback}_superclass_callbacks -
|
580
|
-
_#{callback}_callbacks) - _removed_#{callback}_callbacks
|
581
|
-
|
582
|
-
callbacks.each do |callback|
|
583
|
-
if new_index = _#{callback}_callbacks.index(callback)
|
584
|
-
index = new_index + 1
|
585
|
-
else
|
586
|
-
changed = true
|
587
|
-
_#{callback}_callbacks.insert(index, callback)
|
588
|
-
index = index + 1
|
589
|
-
end
|
590
|
-
end
|
591
|
-
changed
|
592
|
-
end
|
593
|
-
METHOD
|
594
|
-
|
595
|
-
__define_runner(callback)
|
596
|
-
end
|
597
|
-
end
|
598
|
-
end
|
599
|
-
end
|
600
|
-
end
|