activesupport 2.3.5 → 3.0.0.beta3
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/CHANGELOG +66 -9
- data/lib/active_support/all.rb +2 -7
- data/lib/active_support/backtrace_cleaner.rb +31 -9
- data/lib/active_support/base64.rb +9 -0
- data/lib/active_support/basic_object.rb +7 -10
- data/lib/active_support/benchmarkable.rb +60 -0
- data/lib/active_support/buffered_logger.rb +14 -9
- data/lib/active_support/cache/compressed_mem_cache_store.rb +2 -0
- data/lib/active_support/cache/file_store.rb +35 -17
- data/lib/active_support/cache/mem_cache_store.rb +32 -23
- data/lib/active_support/cache/memory_store.rb +17 -10
- data/lib/active_support/cache/strategy/local_cache.rb +9 -1
- data/lib/active_support/cache.rb +75 -55
- data/lib/active_support/callbacks.rb +490 -169
- data/lib/active_support/concern.rb +29 -0
- data/lib/active_support/configurable.rb +35 -0
- data/lib/active_support/core_ext/array/access.rb +39 -46
- data/lib/active_support/core_ext/array/conversions.rb +145 -182
- data/lib/active_support/core_ext/array/extract_options.rb +26 -17
- data/lib/active_support/core_ext/array/grouping.rb +87 -93
- data/lib/active_support/core_ext/array/random_access.rb +4 -10
- data/lib/active_support/core_ext/array/uniq_by.rb +17 -0
- data/lib/active_support/core_ext/array/wrap.rb +22 -0
- data/lib/active_support/core_ext/array.rb +2 -10
- data/lib/active_support/core_ext/big_decimal/conversions.rb +27 -0
- data/lib/active_support/core_ext/big_decimal.rb +1 -0
- data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +16 -20
- data/lib/active_support/core_ext/cgi.rb +0 -4
- data/lib/active_support/core_ext/class/attribute.rb +70 -0
- data/lib/active_support/core_ext/class/attribute_accessors.rb +40 -31
- data/lib/active_support/core_ext/class/delegating_attributes.rb +37 -40
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +100 -11
- data/lib/active_support/core_ext/class/subclasses.rb +55 -0
- data/lib/active_support/core_ext/class.rb +1 -1
- data/lib/active_support/core_ext/date/acts_like.rb +8 -0
- data/lib/active_support/core_ext/date/calculations.rb +218 -228
- data/lib/active_support/core_ext/date/conversions.rb +87 -96
- data/lib/active_support/core_ext/date/freeze.rb +31 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +13 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +97 -110
- data/lib/active_support/core_ext/date_time/conversions.rb +85 -85
- data/lib/active_support/core_ext/date_time/zones.rb +17 -0
- data/lib/active_support/core_ext/enumerable.rb +18 -13
- data/lib/active_support/core_ext/exception.rb +1 -43
- data/lib/active_support/core_ext/file/atomic.rb +35 -40
- data/lib/active_support/core_ext/file/path.rb +5 -0
- data/lib/active_support/core_ext/file.rb +0 -4
- data/lib/active_support/core_ext/float/rounding.rb +15 -20
- data/lib/active_support/core_ext/float.rb +0 -6
- data/lib/active_support/core_ext/hash/conversions.rb +255 -229
- data/lib/active_support/core_ext/hash/deep_merge.rb +12 -19
- data/lib/active_support/core_ext/hash/diff.rb +11 -17
- data/lib/active_support/core_ext/hash/except.rb +21 -22
- data/lib/active_support/core_ext/hash/indifferent_access.rb +8 -137
- data/lib/active_support/core_ext/hash/keys.rb +38 -45
- data/lib/active_support/core_ext/hash/reverse_merge.rb +25 -32
- data/lib/active_support/core_ext/hash/slice.rb +35 -37
- data/lib/active_support/core_ext/hash.rb +8 -14
- data/lib/active_support/core_ext/integer/inflections.rb +10 -16
- data/lib/active_support/core_ext/integer/multiple.rb +6 -0
- data/lib/active_support/core_ext/integer/time.rb +36 -42
- data/lib/active_support/core_ext/integer.rb +1 -7
- data/lib/active_support/core_ext/kernel/debugger.rb +1 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +9 -7
- data/lib/active_support/core_ext/kernel/requires.rb +3 -1
- data/lib/active_support/core_ext/kernel/singleton_class.rb +13 -0
- data/lib/active_support/core_ext/kernel.rb +1 -1
- data/lib/active_support/core_ext/load_error.rb +16 -32
- data/lib/active_support/core_ext/logger.rb +3 -2
- data/lib/active_support/core_ext/module/aliasing.rb +64 -68
- data/lib/active_support/core_ext/module/anonymous.rb +24 -0
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +1 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +4 -4
- data/lib/active_support/core_ext/module/attribute_accessors.rb +48 -42
- data/lib/active_support/core_ext/module/delegation.rb +22 -11
- data/lib/active_support/core_ext/module/deprecation.rb +9 -0
- data/lib/active_support/core_ext/module/introspection.rb +77 -79
- data/lib/active_support/core_ext/module/method_names.rb +14 -0
- data/lib/active_support/core_ext/module/reachable.rb +10 -0
- data/lib/active_support/core_ext/module/remove_method.rb +6 -0
- data/lib/active_support/core_ext/module/synchronization.rb +4 -1
- data/lib/active_support/core_ext/module.rb +7 -18
- data/lib/active_support/core_ext/name_error.rb +3 -4
- data/lib/active_support/core_ext/numeric/bytes.rb +35 -41
- data/lib/active_support/core_ext/numeric/time.rb +70 -74
- data/lib/active_support/core_ext/numeric.rb +1 -8
- data/lib/active_support/core_ext/object/acts_like.rb +10 -0
- data/lib/active_support/core_ext/object/blank.rb +20 -2
- data/lib/active_support/core_ext/object/conversions.rb +4 -15
- data/lib/active_support/core_ext/object/duplicable.rb +65 -0
- data/lib/active_support/core_ext/object/extending.rb +8 -77
- data/lib/active_support/core_ext/object/instance_variables.rb +0 -7
- data/lib/active_support/core_ext/object/misc.rb +2 -90
- data/lib/active_support/core_ext/object/returning.rb +42 -0
- data/lib/active_support/core_ext/object/to_param.rb +49 -0
- data/lib/active_support/core_ext/object/to_query.rb +27 -0
- data/lib/active_support/core_ext/{try.rb → object/try.rb} +4 -4
- data/lib/active_support/core_ext/object/with_options.rb +24 -0
- data/lib/active_support/core_ext/object.rb +10 -2
- data/lib/active_support/core_ext/proc.rb +3 -1
- data/lib/active_support/core_ext/process/daemon.rb +17 -19
- data/lib/active_support/core_ext/range/blockless_step.rb +24 -27
- data/lib/active_support/core_ext/range/conversions.rb +17 -23
- data/lib/active_support/core_ext/range/include_range.rb +18 -27
- data/lib/active_support/core_ext/range/overlaps.rb +6 -13
- data/lib/active_support/core_ext/range.rb +2 -9
- data/lib/active_support/core_ext/regexp.rb +5 -0
- data/lib/active_support/core_ext/rexml.rb +12 -7
- data/lib/active_support/core_ext/string/access.rb +88 -95
- data/lib/active_support/core_ext/string/behavior.rb +6 -12
- data/lib/active_support/core_ext/string/conversions.rb +20 -21
- data/lib/active_support/core_ext/string/exclude.rb +6 -0
- data/lib/active_support/core_ext/string/filters.rb +17 -23
- data/lib/active_support/core_ext/string/inflections.rb +147 -154
- data/lib/active_support/core_ext/string/interpolation.rb +1 -0
- data/lib/active_support/core_ext/string/multibyte.rb +68 -74
- data/lib/active_support/core_ext/string/output_safety.rb +105 -44
- data/lib/active_support/core_ext/string/starts_ends_with.rb +3 -34
- data/lib/active_support/core_ext/string/xchar.rb +10 -3
- data/lib/active_support/core_ext/string.rb +6 -20
- data/lib/active_support/core_ext/time/acts_like.rb +8 -0
- data/lib/active_support/core_ext/time/calculations.rb +276 -299
- data/lib/active_support/core_ext/time/conversions.rb +79 -84
- data/lib/active_support/core_ext/time/marshal.rb +56 -0
- data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +10 -0
- data/lib/active_support/core_ext/time/zones.rb +73 -81
- data/lib/active_support/core_ext/uri.rb +2 -1
- data/lib/active_support/core_ext.rb +2 -7
- data/lib/active_support/dependencies/autoload.rb +50 -0
- data/lib/active_support/dependencies.rb +168 -197
- data/lib/active_support/deprecation/behaviors.rb +38 -0
- data/lib/active_support/deprecation/method_wrappers.rb +29 -0
- data/lib/active_support/deprecation/proxy_wrappers.rb +74 -0
- data/lib/active_support/deprecation/reporting.rb +56 -0
- data/lib/active_support/deprecation.rb +9 -187
- data/lib/active_support/duration.rb +6 -2
- data/lib/active_support/hash_with_indifferent_access.rb +141 -0
- data/lib/active_support/i18n.rb +3 -0
- data/lib/active_support/inflections.rb +1 -1
- data/lib/active_support/inflector/inflections.rb +211 -0
- data/lib/active_support/inflector/methods.rb +141 -0
- data/lib/active_support/inflector/transliterate.rb +77 -0
- data/lib/active_support/inflector.rb +4 -403
- data/lib/active_support/json/backends/jsongem.rb +16 -10
- data/lib/active_support/json/backends/yajl.rb +40 -0
- data/lib/active_support/json/backends/yaml.rb +14 -8
- data/lib/active_support/json/decoding.rb +17 -1
- data/lib/active_support/json/encoding.rb +164 -35
- data/lib/active_support/json/variable.rb +4 -3
- data/lib/active_support/lazy_load_hooks.rb +17 -0
- data/lib/active_support/memoizable.rb +8 -5
- data/lib/active_support/message_encryptor.rb +1 -0
- data/lib/active_support/message_verifier.rb +12 -29
- data/lib/active_support/multibyte/chars.rb +88 -31
- data/lib/active_support/multibyte/unicode_database.rb +5 -5
- data/lib/active_support/multibyte/utils.rb +6 -7
- data/lib/active_support/multibyte.rb +11 -6
- data/lib/active_support/notifications/fanout.rb +83 -0
- data/lib/active_support/notifications/instrumenter.rb +50 -0
- data/lib/active_support/notifications.rb +81 -0
- data/lib/active_support/option_merger.rb +2 -0
- data/lib/active_support/ordered_hash.rb +28 -11
- data/lib/active_support/ordered_options.rb +9 -1
- data/lib/active_support/railtie.rb +64 -0
- data/lib/active_support/rescuable.rb +11 -6
- data/lib/active_support/ruby/shim.rb +21 -0
- data/lib/active_support/test_case.rb +10 -8
- data/lib/active_support/testing/assertions.rb +17 -0
- data/lib/active_support/testing/declarative.rb +31 -12
- data/lib/active_support/testing/deprecation.rb +8 -10
- data/lib/active_support/testing/isolation.rb +153 -0
- data/lib/active_support/testing/pending.rb +48 -0
- data/lib/active_support/testing/performance.rb +342 -339
- data/lib/active_support/testing/setup_and_teardown.rb +48 -31
- data/lib/active_support/time/autoload.rb +5 -0
- data/lib/active_support/time.rb +34 -0
- data/lib/active_support/time_with_zone.rb +18 -12
- data/lib/active_support/values/time_zone.rb +51 -68
- data/lib/active_support/version.rb +5 -4
- data/lib/active_support/whiny_nil.rb +5 -9
- data/lib/active_support/xml_mini/jdom.rb +13 -7
- data/lib/active_support/xml_mini/libxml.rb +38 -91
- data/lib/active_support/xml_mini/libxmlsax.rb +85 -0
- data/lib/active_support/xml_mini/nokogiri.rb +40 -31
- data/lib/active_support/xml_mini/nokogirisax.rb +83 -0
- data/lib/active_support/xml_mini/rexml.rb +30 -9
- data/lib/active_support/xml_mini.rb +2 -0
- data/lib/active_support.rb +46 -30
- metadata +136 -215
- data/lib/active_support/cache/drb_store.rb +0 -14
- data/lib/active_support/core_ext/array/wrapper.rb +0 -24
- data/lib/active_support/core_ext/base64/encoding.rb +0 -16
- data/lib/active_support/core_ext/base64.rb +0 -4
- data/lib/active_support/core_ext/bigdecimal/conversions.rb +0 -37
- data/lib/active_support/core_ext/bigdecimal.rb +0 -6
- data/lib/active_support/core_ext/blank.rb +0 -2
- data/lib/active_support/core_ext/class/removal.rb +0 -50
- data/lib/active_support/core_ext/date/behavior.rb +0 -42
- data/lib/active_support/core_ext/date.rb +0 -10
- data/lib/active_support/core_ext/date_time.rb +0 -12
- data/lib/active_support/core_ext/duplicable.rb +0 -43
- data/lib/active_support/core_ext/float/time.rb +0 -27
- data/lib/active_support/core_ext/integer/even_odd.rb +0 -29
- data/lib/active_support/core_ext/kernel/daemonizing.rb +0 -7
- data/lib/active_support/core_ext/module/inclusion.rb +0 -30
- data/lib/active_support/core_ext/module/loading.rb +0 -23
- data/lib/active_support/core_ext/module/model_naming.rb +0 -25
- data/lib/active_support/core_ext/numeric/conversions.rb +0 -19
- data/lib/active_support/core_ext/object/metaclass.rb +0 -13
- data/lib/active_support/core_ext/pathname/clean_within.rb +0 -14
- data/lib/active_support/core_ext/pathname.rb +0 -7
- data/lib/active_support/core_ext/string/bytesize.rb +0 -5
- data/lib/active_support/core_ext/string/iterators.rb +0 -23
- data/lib/active_support/core_ext/symbol.rb +0 -14
- data/lib/active_support/core_ext/time/behavior.rb +0 -13
- data/lib/active_support/core_ext/time.rb +0 -42
- data/lib/active_support/json/encoders/date.rb +0 -22
- data/lib/active_support/json/encoders/date_time.rb +0 -22
- data/lib/active_support/json/encoders/enumerable.rb +0 -17
- data/lib/active_support/json/encoders/false_class.rb +0 -7
- data/lib/active_support/json/encoders/hash.rb +0 -56
- data/lib/active_support/json/encoders/nil_class.rb +0 -7
- data/lib/active_support/json/encoders/numeric.rb +0 -21
- data/lib/active_support/json/encoders/object.rb +0 -10
- data/lib/active_support/json/encoders/regexp.rb +0 -9
- data/lib/active_support/json/encoders/string.rb +0 -9
- data/lib/active_support/json/encoders/symbol.rb +0 -5
- data/lib/active_support/json/encoders/time.rb +0 -22
- data/lib/active_support/json/encoders/true_class.rb +0 -7
- data/lib/active_support/vendor/builder-2.1.2/blankslate.rb +0 -113
- data/lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb +0 -20
- data/lib/active_support/vendor/builder-2.1.2/builder/css.rb +0 -250
- data/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb +0 -115
- data/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb +0 -139
- data/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb +0 -63
- data/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb +0 -328
- data/lib/active_support/vendor/builder-2.1.2/builder.rb +0 -13
- data/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE +0 -20
- data/lib/active_support/vendor/i18n-0.1.3/README.textile +0 -20
- data/lib/active_support/vendor/i18n-0.1.3/Rakefile +0 -5
- data/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec +0 -27
- data/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb +0 -214
- data/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb +0 -53
- data/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb +0 -199
- data/lib/active_support/vendor/i18n-0.1.3/test/all.rb +0 -5
- data/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb +0 -99
- data/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb +0 -124
- data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb +0 -1
- data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml +0 -3
- data/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb +0 -567
- data/lib/active_support/vendor/memcache-client-1.7.4/memcache.rb +0 -1107
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/data_timezone.rb +0 -47
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/data_timezone_info.rb +0 -228
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Algiers.rb +0 -55
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Cairo.rb +0 -219
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Casablanca.rb +0 -40
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Harare.rb +0 -18
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Johannesburg.rb +0 -25
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Monrovia.rb +0 -22
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Nairobi.rb +0 -23
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/Buenos_Aires.rb +0 -166
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/San_Juan.rb +0 -86
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Bogota.rb +0 -23
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Caracas.rb +0 -23
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Chicago.rb +0 -283
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Chihuahua.rb +0 -136
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Denver.rb +0 -204
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Godthab.rb +0 -161
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Guatemala.rb +0 -27
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Halifax.rb +0 -274
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Indiana/Indianapolis.rb +0 -149
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Juneau.rb +0 -194
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/La_Paz.rb +0 -22
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Lima.rb +0 -35
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Los_Angeles.rb +0 -232
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Mazatlan.rb +0 -139
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Mexico_City.rb +0 -144
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Monterrey.rb +0 -131
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/New_York.rb +0 -282
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Phoenix.rb +0 -30
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Regina.rb +0 -74
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Santiago.rb +0 -205
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Sao_Paulo.rb +0 -171
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/St_Johns.rb +0 -288
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Tijuana.rb +0 -196
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Almaty.rb +0 -67
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Baghdad.rb +0 -73
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Baku.rb +0 -161
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Bangkok.rb +0 -20
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Chongqing.rb +0 -33
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Colombo.rb +0 -30
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Dhaka.rb +0 -27
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Hong_Kong.rb +0 -87
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Irkutsk.rb +0 -165
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Jakarta.rb +0 -30
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Jerusalem.rb +0 -163
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kabul.rb +0 -20
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kamchatka.rb +0 -163
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Karachi.rb +0 -30
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Katmandu.rb +0 -20
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kolkata.rb +0 -25
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Krasnoyarsk.rb +0 -163
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kuala_Lumpur.rb +0 -31
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kuwait.rb +0 -18
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Magadan.rb +0 -163
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Muscat.rb +0 -18
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Novosibirsk.rb +0 -164
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Rangoon.rb +0 -24
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Riyadh.rb +0 -18
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Seoul.rb +0 -34
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Shanghai.rb +0 -35
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Singapore.rb +0 -33
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Taipei.rb +0 -59
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tashkent.rb +0 -47
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tbilisi.rb +0 -78
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tehran.rb +0 -121
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tokyo.rb +0 -30
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Ulaanbaatar.rb +0 -65
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Urumqi.rb +0 -33
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Vladivostok.rb +0 -164
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yakutsk.rb +0 -163
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yekaterinburg.rb +0 -165
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yerevan.rb +0 -165
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/Azores.rb +0 -270
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/Cape_Verde.rb +0 -23
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/South_Georgia.rb +0 -18
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Adelaide.rb +0 -187
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Brisbane.rb +0 -35
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Darwin.rb +0 -29
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Hobart.rb +0 -193
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Melbourne.rb +0 -185
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Perth.rb +0 -37
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Sydney.rb +0 -185
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Etc/UTC.rb +0 -16
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Amsterdam.rb +0 -228
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Athens.rb +0 -185
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Belgrade.rb +0 -163
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Berlin.rb +0 -188
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Bratislava.rb +0 -13
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Brussels.rb +0 -232
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Bucharest.rb +0 -181
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Budapest.rb +0 -197
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Copenhagen.rb +0 -179
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Dublin.rb +0 -276
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Helsinki.rb +0 -163
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Istanbul.rb +0 -218
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Kiev.rb +0 -168
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Lisbon.rb +0 -268
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Ljubljana.rb +0 -13
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/London.rb +0 -288
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Madrid.rb +0 -211
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Minsk.rb +0 -170
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Moscow.rb +0 -181
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Paris.rb +0 -232
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Prague.rb +0 -187
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Riga.rb +0 -176
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Rome.rb +0 -215
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Sarajevo.rb +0 -13
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Skopje.rb +0 -13
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Sofia.rb +0 -173
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Stockholm.rb +0 -165
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Tallinn.rb +0 -172
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Vienna.rb +0 -183
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Vilnius.rb +0 -170
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Warsaw.rb +0 -212
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Zagreb.rb +0 -13
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Auckland.rb +0 -202
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Fiji.rb +0 -23
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Guam.rb +0 -22
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Honolulu.rb +0 -28
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Majuro.rb +0 -20
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Midway.rb +0 -25
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Noumea.rb +0 -25
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Pago_Pago.rb +0 -26
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Port_Moresby.rb +0 -20
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Tongatapu.rb +0 -27
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/info_timezone.rb +0 -52
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/linked_timezone.rb +0 -51
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/linked_timezone_info.rb +0 -44
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/offset_rationals.rb +0 -98
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/ruby_core_support.rb +0 -56
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/time_or_datetime.rb +0 -292
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb +0 -508
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_definition.rb +0 -56
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_info.rb +0 -40
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_offset_info.rb +0 -94
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb +0 -198
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_transition_info.rb +0 -129
- data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo.rb +0 -33
- data/lib/active_support/vendor.rb +0 -28
- data/lib/activesupport.rb +0 -2
|
@@ -1,3 +1,8 @@
|
|
|
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
|
+
|
|
1
6
|
module ActiveSupport
|
|
2
7
|
# Callbacks are hooks into the lifecycle of an object that allow you to trigger logic
|
|
3
8
|
# before or after an alteration of the object state.
|
|
@@ -8,23 +13,23 @@ module ActiveSupport
|
|
|
8
13
|
# class Storage
|
|
9
14
|
# include ActiveSupport::Callbacks
|
|
10
15
|
#
|
|
11
|
-
# define_callbacks :
|
|
16
|
+
# define_callbacks :save
|
|
12
17
|
# end
|
|
13
18
|
#
|
|
14
19
|
# class ConfigStorage < Storage
|
|
15
|
-
#
|
|
20
|
+
# set_callback :save, :before, :saving_message
|
|
16
21
|
# def saving_message
|
|
17
22
|
# puts "saving..."
|
|
18
23
|
# end
|
|
19
24
|
#
|
|
20
|
-
#
|
|
25
|
+
# set_callback :save, :after do |object|
|
|
21
26
|
# puts "saved"
|
|
22
27
|
# end
|
|
23
28
|
#
|
|
24
29
|
# def save
|
|
25
|
-
# run_callbacks
|
|
26
|
-
#
|
|
27
|
-
#
|
|
30
|
+
# run_callbacks :save do
|
|
31
|
+
# puts "- save"
|
|
32
|
+
# end
|
|
28
33
|
# end
|
|
29
34
|
# end
|
|
30
35
|
#
|
|
@@ -42,28 +47,28 @@ module ActiveSupport
|
|
|
42
47
|
# class Storage
|
|
43
48
|
# include ActiveSupport::Callbacks
|
|
44
49
|
#
|
|
45
|
-
# define_callbacks :
|
|
50
|
+
# define_callbacks :save
|
|
46
51
|
#
|
|
47
|
-
#
|
|
52
|
+
# set_callback :save, :before, :prepare
|
|
48
53
|
# def prepare
|
|
49
54
|
# puts "preparing save"
|
|
50
55
|
# end
|
|
51
56
|
# end
|
|
52
57
|
#
|
|
53
58
|
# class ConfigStorage < Storage
|
|
54
|
-
#
|
|
59
|
+
# set_callback :save, :before, :saving_message
|
|
55
60
|
# def saving_message
|
|
56
61
|
# puts "saving..."
|
|
57
62
|
# end
|
|
58
63
|
#
|
|
59
|
-
#
|
|
64
|
+
# set_callback :save, :after do |object|
|
|
60
65
|
# puts "saved"
|
|
61
66
|
# end
|
|
62
67
|
#
|
|
63
68
|
# def save
|
|
64
|
-
# run_callbacks
|
|
65
|
-
#
|
|
66
|
-
#
|
|
69
|
+
# run_callbacks :save do
|
|
70
|
+
# puts "- save"
|
|
71
|
+
# end
|
|
67
72
|
# end
|
|
68
73
|
# end
|
|
69
74
|
#
|
|
@@ -75,205 +80,521 @@ module ActiveSupport
|
|
|
75
80
|
# saving...
|
|
76
81
|
# - save
|
|
77
82
|
# saved
|
|
83
|
+
#
|
|
78
84
|
module Callbacks
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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
|
|
84
107
|
end
|
|
85
108
|
|
|
86
|
-
def
|
|
87
|
-
|
|
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
|
|
88
121
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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]}
|
|
95
164
|
end
|
|
96
|
-
|
|
165
|
+
RUBY_EVAL
|
|
97
166
|
end
|
|
98
167
|
|
|
99
|
-
#
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
+
txt, line = <<-RUBY_EVAL, __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
|
+
@klass.class_eval(txt, __FILE__, line)
|
|
218
|
+
"#{name}(halted) do"
|
|
219
|
+
end
|
|
105
220
|
end
|
|
106
|
-
self
|
|
107
221
|
end
|
|
108
222
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
end
|
|
223
|
+
# This will supply contents for around and after filters, but not
|
|
224
|
+
# before filters (for the backward pass).
|
|
225
|
+
def end(key=nil, object=nil)
|
|
226
|
+
return if key && !object.send("_one_time_conditions_valid_#{@callback_id}?")
|
|
112
227
|
|
|
113
|
-
|
|
114
|
-
|
|
228
|
+
if @kind == :around || @kind == :after
|
|
229
|
+
# if condition # after_save :filter_name, :if => :condition
|
|
230
|
+
# filter_name
|
|
231
|
+
# end
|
|
232
|
+
if @kind == :after
|
|
233
|
+
[@compiled_options[0], @filter, @compiled_options[1]].compact.join("\n")
|
|
234
|
+
else
|
|
235
|
+
"end"
|
|
236
|
+
end
|
|
237
|
+
end
|
|
115
238
|
end
|
|
116
239
|
|
|
117
240
|
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
241
|
|
|
125
|
-
|
|
126
|
-
|
|
242
|
+
# Options support the same options as filters themselves (and support
|
|
243
|
+
# symbols, string, procs, and objects), so compile a conditional
|
|
244
|
+
# expression based on the options
|
|
245
|
+
def _compile_options(options)
|
|
246
|
+
return [] if options[:if].empty? && options[:unless].empty?
|
|
247
|
+
|
|
248
|
+
conditions = []
|
|
249
|
+
|
|
250
|
+
unless options[:if].empty?
|
|
251
|
+
conditions << Array.wrap(_compile_filter(options[:if]))
|
|
127
252
|
end
|
|
128
|
-
end
|
|
129
253
|
|
|
130
|
-
|
|
131
|
-
|
|
254
|
+
unless options[:unless].empty?
|
|
255
|
+
conditions << Array.wrap(_compile_filter(options[:unless])).map {|f| "!#{f}"}
|
|
256
|
+
end
|
|
132
257
|
|
|
133
|
-
|
|
134
|
-
@kind = kind
|
|
135
|
-
@method = method
|
|
136
|
-
@identifier = options[:identifier]
|
|
137
|
-
@options = options
|
|
258
|
+
["if #{conditions.flatten.join(" && ")}", "end"]
|
|
138
259
|
end
|
|
139
260
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
261
|
+
# Filters support:
|
|
262
|
+
#
|
|
263
|
+
# Arrays:: Used in conditions. This is used to specify
|
|
264
|
+
# multiple conditions. Used internally to
|
|
265
|
+
# merge conditions from skip_* filters
|
|
266
|
+
# Symbols:: A method to call
|
|
267
|
+
# Strings:: Some content to evaluate
|
|
268
|
+
# Procs:: A proc to call with the object
|
|
269
|
+
# Objects:: An object with a before_foo method on it to call
|
|
270
|
+
#
|
|
271
|
+
# All of these objects are compiled into methods and handled
|
|
272
|
+
# the same after this point:
|
|
273
|
+
#
|
|
274
|
+
# Arrays:: Merged together into a single filter
|
|
275
|
+
# Symbols:: Already methods
|
|
276
|
+
# Strings:: class_eval'ed into methods
|
|
277
|
+
# Procs:: define_method'ed into methods
|
|
278
|
+
# Objects::
|
|
279
|
+
# a method is created that calls the before_foo method
|
|
280
|
+
# on the object.
|
|
281
|
+
#
|
|
282
|
+
def _compile_filter(filter)
|
|
283
|
+
method_name = "_callback_#{@kind}_#{next_id}"
|
|
284
|
+
case filter
|
|
285
|
+
when Array
|
|
286
|
+
filter.map {|f| _compile_filter(f)}
|
|
287
|
+
when Symbol
|
|
288
|
+
filter
|
|
289
|
+
when String
|
|
290
|
+
"(#{filter})"
|
|
291
|
+
when Proc
|
|
292
|
+
@klass.send(:define_method, method_name, &filter)
|
|
293
|
+
return method_name if filter.arity <= 0
|
|
294
|
+
|
|
295
|
+
method_name << (filter.arity == 1 ? "(self)" : " self, Proc.new ")
|
|
144
296
|
else
|
|
145
|
-
(
|
|
297
|
+
@klass.send(:define_method, "#{method_name}_object") { filter }
|
|
298
|
+
|
|
299
|
+
_normalize_legacy_filter(kind, filter)
|
|
300
|
+
scopes = Array.wrap(chain.config[:scope])
|
|
301
|
+
method_to_call = scopes.map{ |s| s.is_a?(Symbol) ? send(s) : s }.join("_")
|
|
302
|
+
|
|
303
|
+
@klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
|
304
|
+
def #{method_name}(&blk)
|
|
305
|
+
#{method_name}_object.send(:#{method_to_call}, self, &blk)
|
|
306
|
+
end
|
|
307
|
+
RUBY_EVAL
|
|
308
|
+
|
|
309
|
+
method_name
|
|
146
310
|
end
|
|
147
311
|
end
|
|
148
312
|
|
|
149
|
-
def
|
|
150
|
-
|
|
313
|
+
def _normalize_legacy_filter(kind, filter)
|
|
314
|
+
if !filter.respond_to?(kind) && filter.respond_to?(:filter)
|
|
315
|
+
filter.singleton_class.class_eval(
|
|
316
|
+
"def #{kind}(context, &block) filter(context, &block) end",
|
|
317
|
+
__FILE__, __LINE__ - 1)
|
|
318
|
+
elsif filter.respond_to?(:before) && filter.respond_to?(:after) && kind == :around
|
|
319
|
+
def filter.around(context)
|
|
320
|
+
should_continue = before(context)
|
|
321
|
+
yield if should_continue
|
|
322
|
+
after(context)
|
|
323
|
+
end
|
|
324
|
+
end
|
|
151
325
|
end
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
# An Array with a compile method
|
|
329
|
+
class CallbackChain < Array
|
|
330
|
+
attr_reader :name, :config
|
|
152
331
|
|
|
153
|
-
def
|
|
154
|
-
|
|
332
|
+
def initialize(name, config)
|
|
333
|
+
@name = name
|
|
334
|
+
@config = {
|
|
335
|
+
:terminator => "false",
|
|
336
|
+
:rescuable => false,
|
|
337
|
+
:scope => [ :kind ]
|
|
338
|
+
}.merge(config)
|
|
155
339
|
end
|
|
156
340
|
|
|
157
|
-
def
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
341
|
+
def compile(key=nil, object=nil)
|
|
342
|
+
method = []
|
|
343
|
+
method << "value = nil"
|
|
344
|
+
method << "halted = false"
|
|
345
|
+
|
|
346
|
+
each do |callback|
|
|
347
|
+
method << callback.start(key, object)
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
if config[:rescuable]
|
|
351
|
+
method << "rescued_error = nil"
|
|
352
|
+
method << "begin"
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
method << "value = yield if block_given? && !halted"
|
|
356
|
+
|
|
357
|
+
if config[:rescuable]
|
|
358
|
+
method << "rescue Exception => e"
|
|
359
|
+
method << "rescued_error = e"
|
|
360
|
+
method << "end"
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
reverse_each do |callback|
|
|
364
|
+
method << callback.end(key, object)
|
|
162
365
|
end
|
|
163
|
-
end
|
|
164
366
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
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."
|
|
367
|
+
method << "raise rescued_error if rescued_error" if config[:rescuable]
|
|
368
|
+
method << "halted ? false : (block_given? ? value : true)"
|
|
369
|
+
method.compact.join("\n")
|
|
171
370
|
end
|
|
371
|
+
end
|
|
172
372
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
373
|
+
module ClassMethods
|
|
374
|
+
# Make the run_callbacks :save method. The generated method takes
|
|
375
|
+
# a block that it'll yield to. It'll call the before and around filters
|
|
376
|
+
# in order, yield the block, and then run the after filters.
|
|
377
|
+
#
|
|
378
|
+
# run_callbacks :save do
|
|
379
|
+
# save
|
|
380
|
+
# end
|
|
381
|
+
#
|
|
382
|
+
# The run_callbacks :save method can optionally take a key, which
|
|
383
|
+
# will be used to compile an optimized callback method for each
|
|
384
|
+
# key. See #define_callbacks for more information.
|
|
385
|
+
#
|
|
386
|
+
def __define_runner(symbol) #:nodoc:
|
|
387
|
+
send("_update_#{symbol}_superclass_callbacks")
|
|
388
|
+
body = send("_#{symbol}_callbacks").compile(nil)
|
|
389
|
+
|
|
390
|
+
body, line = <<-RUBY_EVAL, __LINE__ + 1
|
|
391
|
+
def _run_#{symbol}_callbacks(key = nil, &blk)
|
|
392
|
+
if self.class.send("_update_#{symbol}_superclass_callbacks")
|
|
393
|
+
self.class.__define_runner(#{symbol.inspect})
|
|
394
|
+
return _run_#{symbol}_callbacks(key, &blk)
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
if key
|
|
398
|
+
name = "_run__\#{self.class.name.hash.abs}__#{symbol}__\#{key.hash.abs}__callbacks"
|
|
399
|
+
|
|
400
|
+
unless respond_to?(name)
|
|
401
|
+
self.class.__create_keyed_callback(name, :#{symbol}, self, &blk)
|
|
190
402
|
end
|
|
403
|
+
|
|
404
|
+
send(name, &blk)
|
|
405
|
+
else
|
|
406
|
+
#{body}
|
|
407
|
+
end
|
|
191
408
|
end
|
|
409
|
+
private :_run_#{symbol}_callbacks
|
|
410
|
+
RUBY_EVAL
|
|
411
|
+
|
|
412
|
+
silence_warnings do
|
|
413
|
+
undef_method "_run_#{symbol}_callbacks" if method_defined?("_run_#{symbol}_callbacks")
|
|
414
|
+
class_eval body, __FILE__, line
|
|
192
415
|
end
|
|
416
|
+
end
|
|
193
417
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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
|
|
197
428
|
end
|
|
198
|
-
|
|
429
|
+
end
|
|
199
430
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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")
|
|
203
436
|
|
|
204
|
-
|
|
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
|
+
#
|
|
205
556
|
def define_callbacks(*callbacks)
|
|
557
|
+
config = callbacks.last.is_a?(Hash) ? callbacks.pop : {}
|
|
206
558
|
callbacks.each do |callback|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
if superclass.respond_to?(
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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)
|
|
227
596
|
end
|
|
228
597
|
end
|
|
229
598
|
end
|
|
230
|
-
|
|
231
|
-
# Runs all the callbacks defined for the given options.
|
|
232
|
-
#
|
|
233
|
-
# If a block is given it will be called after each callback receiving as arguments:
|
|
234
|
-
#
|
|
235
|
-
# * the result from the callback
|
|
236
|
-
# * the object which has the callback
|
|
237
|
-
#
|
|
238
|
-
# If the result from the block evaluates to false, the callback chain is stopped.
|
|
239
|
-
#
|
|
240
|
-
# Example:
|
|
241
|
-
# class Storage
|
|
242
|
-
# include ActiveSupport::Callbacks
|
|
243
|
-
#
|
|
244
|
-
# define_callbacks :before_save, :after_save
|
|
245
|
-
# end
|
|
246
|
-
#
|
|
247
|
-
# class ConfigStorage < Storage
|
|
248
|
-
# before_save :pass
|
|
249
|
-
# before_save :pass
|
|
250
|
-
# before_save :stop
|
|
251
|
-
# before_save :pass
|
|
252
|
-
#
|
|
253
|
-
# def pass
|
|
254
|
-
# puts "pass"
|
|
255
|
-
# end
|
|
256
|
-
#
|
|
257
|
-
# def stop
|
|
258
|
-
# puts "stop"
|
|
259
|
-
# return false
|
|
260
|
-
# end
|
|
261
|
-
#
|
|
262
|
-
# def save
|
|
263
|
-
# result = run_callbacks(:before_save) { |result, object| result == false }
|
|
264
|
-
# puts "- save" if result
|
|
265
|
-
# end
|
|
266
|
-
# end
|
|
267
|
-
#
|
|
268
|
-
# config = ConfigStorage.new
|
|
269
|
-
# config.save
|
|
270
|
-
#
|
|
271
|
-
# Output:
|
|
272
|
-
# pass
|
|
273
|
-
# pass
|
|
274
|
-
# stop
|
|
275
|
-
def run_callbacks(kind, options = {}, &block)
|
|
276
|
-
self.class.send("#{kind}_callback_chain").run(self, options, &block)
|
|
277
|
-
end
|
|
278
599
|
end
|
|
279
600
|
end
|