activesupport 3.0.0.rc → 3.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- data/CHANGELOG +42 -37
- data/lib/active_support/base64.rb +3 -3
- data/lib/active_support/benchmarkable.rb +3 -3
- data/lib/active_support/cache.rb +46 -56
- data/lib/active_support/cache/mem_cache_store.rb +3 -4
- data/lib/active_support/cache/memory_store.rb +5 -5
- data/lib/active_support/cache/strategy/local_cache.rb +5 -5
- data/lib/active_support/callbacks.rb +13 -3
- data/lib/active_support/concern.rb +35 -0
- data/lib/active_support/configurable.rb +2 -2
- data/lib/active_support/core_ext/array/conversions.rb +6 -6
- data/lib/active_support/core_ext/array/random_access.rb +4 -4
- data/lib/active_support/core_ext/array/uniq_by.rb +1 -1
- data/lib/active_support/core_ext/array/wrap.rb +30 -4
- data/lib/active_support/core_ext/class/attribute.rb +27 -4
- data/lib/active_support/core_ext/class/attribute_accessors.rb +16 -0
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +25 -3
- data/lib/active_support/core_ext/date/calculations.rb +15 -15
- data/lib/active_support/core_ext/date_time/conversions.rb +6 -6
- data/lib/active_support/core_ext/date_time/zones.rb +1 -1
- data/lib/active_support/core_ext/enumerable.rb +6 -5
- data/lib/active_support/core_ext/hash/conversions.rb +11 -11
- data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -3
- data/lib/active_support/core_ext/integer/time.rb +2 -2
- data/lib/active_support/core_ext/kernel/reporting.rb +1 -1
- data/lib/active_support/core_ext/module/anonymous.rb +1 -1
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +2 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +1 -1
- data/lib/active_support/core_ext/module/remove_method.rb +1 -1
- data/lib/active_support/core_ext/module/synchronization.rb +2 -2
- data/lib/active_support/core_ext/numeric/time.rb +9 -9
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/object/blank.rb +1 -1
- data/lib/active_support/core_ext/object/instance_variables.rb +5 -5
- data/lib/active_support/core_ext/object/returning.rb +43 -0
- data/lib/active_support/core_ext/range/conversions.rb +1 -1
- data/lib/active_support/core_ext/string/access.rb +7 -7
- data/lib/active_support/core_ext/string/inflections.rb +8 -6
- data/lib/active_support/core_ext/string/multibyte.rb +5 -5
- data/lib/active_support/core_ext/time/calculations.rb +2 -2
- data/lib/active_support/core_ext/time/conversions.rb +1 -1
- data/lib/active_support/core_ext/time/zones.rb +3 -3
- data/lib/active_support/dependencies.rb +56 -38
- data/lib/active_support/duration.rb +1 -1
- data/lib/active_support/hash_with_indifferent_access.rb +9 -3
- data/lib/active_support/i18n_railtie.rb +1 -1
- data/lib/active_support/lazy_load_hooks.rb +20 -1
- data/lib/active_support/locale/en.yml +3 -3
- data/lib/active_support/log_subscriber.rb +32 -33
- data/lib/active_support/log_subscriber/test_helper.rb +1 -1
- data/lib/active_support/message_encryptor.rb +17 -17
- data/lib/active_support/message_verifier.rb +7 -7
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/multibyte/chars.rb +37 -36
- data/lib/active_support/multibyte/unicode.rb +4 -4
- data/lib/active_support/notifications.rb +3 -3
- data/lib/active_support/secure_random.rb +13 -13
- data/lib/active_support/testing/assertions.rb +8 -6
- data/lib/active_support/testing/declarative.rb +4 -4
- data/lib/active_support/testing/isolation.rb +1 -1
- data/lib/active_support/testing/pending.rb +3 -3
- data/lib/active_support/testing/performance.rb +9 -5
- data/lib/active_support/time_with_zone.rb +2 -2
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/nokogiri.rb +6 -1
- data/lib/active_support/xml_mini/nokogirisax.rb +7 -2
- data/lib/active_support/xml_mini/rexml.rb +1 -1
- metadata +5 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
*Rails 3.0.0 [release candidate 2] (August 23rd, 2010)*
|
2
|
+
|
3
|
+
* No material changes (see http://github.com/rails/rails/compare/v3.0.0_RC...v3.0.0_RC2 for gory details)
|
4
|
+
|
5
|
+
|
1
6
|
*Rails 3.0.0 [release candidate] (July 26th, 2010)*
|
2
7
|
|
3
8
|
* Removed Object#returning, Object#tap should be used instead. [Santiago Pastorino]
|
@@ -90,7 +95,7 @@
|
|
90
95
|
|
91
96
|
* Rename #metaclass to #singleton_class now that ruby-core has decided [JK]
|
92
97
|
|
93
|
-
* New assertions assert_blank and assert_present. #4299 [Juanjo Bazan]
|
98
|
+
* New assertions assert_blank and assert_present. #4299 [Juanjo Bazan]
|
94
99
|
|
95
100
|
* Use Object#singleton_class instead of #metaclass. Prefer Ruby's choice. [Jeremy Kemper]
|
96
101
|
|
@@ -243,10 +248,10 @@ ActiveSupport.escape_html_entities_in_json from true to false to match previousl
|
|
243
248
|
* Fix Ruby's Time marshaling bug in pre-1.9 versions of Ruby: utc instances are now correctly unmarshaled with a utc zone instead of the system local zone [#900 state:resolved] [Luca Guidi, Geoff Buesing]
|
244
249
|
|
245
250
|
* Add Array#in_groups which splits or iterates over the array in specified number of groups. #579. [Adrian Mugnolo] Example:
|
246
|
-
|
251
|
+
|
247
252
|
a = (1..10).to_a
|
248
|
-
a.in_groups(3)
|
249
|
-
a.in_groups(3, false)
|
253
|
+
a.in_groups(3) # => [[1, 2, 3, 4], [5, 6, 7, nil], [8, 9, 10, nil]]
|
254
|
+
a.in_groups(3, false) # => [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]
|
250
255
|
|
251
256
|
* Fix TimeWithZone unmarshaling: coerce unmarshaled Time instances to utc, because Ruby's marshaling of Time instances doesn't respect the zone [Geoff Buesing]
|
252
257
|
|
@@ -331,7 +336,7 @@ ActiveSupport.escape_html_entities_in_json from true to false to match previousl
|
|
331
336
|
|
332
337
|
* TZInfo: Removing unneeded TimezoneProxy class [Geoff Buesing]
|
333
338
|
|
334
|
-
* TZInfo: Removing unneeded TimezoneIndexDefinition, since we're not including Indexes::Timezones [Geoff Buesing]
|
339
|
+
* TZInfo: Removing unneeded TimezoneIndexDefinition, since we're not including Indexes::Timezones [Geoff Buesing]
|
335
340
|
|
336
341
|
* Removing unnecessary uses_tzinfo helper from tests, given that TZInfo is now bundled [Geoff Buesing]
|
337
342
|
|
@@ -339,7 +344,7 @@ ActiveSupport.escape_html_entities_in_json from true to false to match previousl
|
|
339
344
|
|
340
345
|
* TimeWithZone#marshal_load does zone lookup via Time.get_zone, so that tzinfo/Olson identifiers are handled [Geoff Buesing]
|
341
346
|
|
342
|
-
* Time.zone= accepts TZInfo::Timezone instances and Olson identifiers; wraps result in TimeZone instance [Geoff Buesing]
|
347
|
+
* Time.zone= accepts TZInfo::Timezone instances and Olson identifiers; wraps result in TimeZone instance [Geoff Buesing]
|
343
348
|
|
344
349
|
* TimeWithZone time conversions don't need to be wrapped in TimeOrDateTime, because TZInfo does this internally [Geoff Buesing]
|
345
350
|
|
@@ -433,7 +438,7 @@ ActiveSupport.escape_html_entities_in_json from true to false to match previousl
|
|
433
438
|
|
434
439
|
* TimeZone#to_s uses UTC rather than GMT; reapplying change that was undone in [8679]. #1689 [Cheah Chu Yeow]
|
435
440
|
|
436
|
-
* Time.days_in_month defaults to current year if no year is supplied as argument #10799 [Radar], uses Date.gregorian_leap? to determine leap year, and uses constant lookup to determine days in month [Geoff Buesing]
|
441
|
+
* Time.days_in_month defaults to current year if no year is supplied as argument #10799 [Radar], uses Date.gregorian_leap? to determine leap year, and uses constant lookup to determine days in month [Geoff Buesing]
|
437
442
|
|
438
443
|
* Adding Time and DateTime #compare_with_coercion, which layers behavior on #<=> so that any combination of Time, DateTime and ActiveSupport::TimeWithZone instances can be chronologically compared [Geoff Buesing]
|
439
444
|
|
@@ -510,7 +515,7 @@ ActiveSupport.escape_html_entities_in_json from true to false to match previousl
|
|
510
515
|
|
511
516
|
* Introduce a base class for all test cases used by rails applications. ActiveSupport::TestCase [Michael Koziarski]
|
512
517
|
|
513
|
-
The intention is to use this to reduce the amount of monkeypatching / overriding that
|
518
|
+
The intention is to use this to reduce the amount of monkeypatching / overriding that
|
514
519
|
is done to test/unit's classes.
|
515
520
|
|
516
521
|
* Document Enumerable and Hash #to_json. #9970 [Cheah Chu Yeow]
|
@@ -679,14 +684,14 @@ ActiveSupport.escape_html_entities_in_json from true to false to match previousl
|
|
679
684
|
<name>David</name>
|
680
685
|
<avatar type="file" name="me.jpg" content_type="image/jpg">R0lGODlhkACZAPUAAM5lcfjrtMQCG=\n</avatar>
|
681
686
|
</person>
|
682
|
-
|
687
|
+
|
683
688
|
...becomes:
|
684
|
-
|
689
|
+
|
685
690
|
attributes = { :person => { :name => "David", :avatar => #<StringIO> } }
|
686
691
|
attributes[:person][:avatar].content_type # => "image/jpg"
|
687
692
|
attributes[:person][:avatar].original_filename # => "me.jpg"
|
688
693
|
attributes[:person][:avatar].read # => binary data of the file
|
689
|
-
|
694
|
+
|
690
695
|
Which is duck-type compatible with the files that you get when doing multipart uploads through HTML.
|
691
696
|
|
692
697
|
* Improved multibyte performance by relying less on exception raising #8159 [Blaine]
|
@@ -889,11 +894,11 @@ public for compatibility. [Jeremy Kemper]
|
|
889
894
|
class Content < ActiveRecord::Base
|
890
895
|
# has a title attribute
|
891
896
|
end
|
892
|
-
|
897
|
+
|
893
898
|
class Email < ActiveRecord::Base
|
894
899
|
alias_attribute :subject, :title
|
895
900
|
end
|
896
|
-
|
901
|
+
|
897
902
|
e = Email.find(1)
|
898
903
|
e.title # => "Superstars"
|
899
904
|
e.subject # => "Superstars"
|
@@ -942,7 +947,7 @@ public for compatibility. [Jeremy Kemper]
|
|
942
947
|
* Enhance Symbol#to_proc so it works with list objects, such as multi-dimensional arrays. Closes #5295 [nov@yo.rim.or.jp]. Example:
|
943
948
|
|
944
949
|
{1 => "one", 2 => "two", 3 => "three"}.sort_by(&:first).map(&:last)
|
945
|
-
|
950
|
+
# => ["one", "two", "three"]
|
946
951
|
|
947
952
|
* Added Hash.create_from_xml(string) which will create a hash from a XML string and even typecast if possible [David Heinemeier Hansson]. Example:
|
948
953
|
|
@@ -952,9 +957,9 @@ public for compatibility. [Jeremy Kemper]
|
|
952
957
|
<created-at type="date">2004-10-10</created-at>
|
953
958
|
</note>
|
954
959
|
EOT
|
955
|
-
|
960
|
+
|
956
961
|
...would return:
|
957
|
-
|
962
|
+
|
958
963
|
{ :note => { :title => "This is a note", :created_at => Date.new(2004, 10, 10) } }
|
959
964
|
|
960
965
|
* Added Jim Weirich's excellent FlexMock class to vendor (Copyright 2003, 2004 by Jim Weirich (jim@weriichhouse.org)) -- it's not automatically required, though, so require 'flexmock' is still necessary [David Heinemeier Hansson]
|
@@ -966,28 +971,28 @@ public for compatibility. [Jeremy Kemper]
|
|
966
971
|
* Add OrderedHash#values. [Sam Stephenson]
|
967
972
|
|
968
973
|
* Added Array#to_s(:db) that'll produce a comma-separated list of ids [David Heinemeier Hansson]. Example:
|
969
|
-
|
974
|
+
|
970
975
|
Purchase.find(:all, :conditions => "product_id IN (#{shops.products.to_s(:db)})"
|
971
976
|
|
972
|
-
* Normalize classify's argument to a String so that it plays nice with Symbols. [Marcel Molina Jr.]
|
977
|
+
* Normalize classify's argument to a String so that it plays nice with Symbols. [Marcel Molina Jr.]
|
973
978
|
|
974
979
|
* Strip out leading schema name in classify. References #5139. [Michael Schoen]
|
975
980
|
|
976
981
|
* Remove Enumerable#first_match since break(value) handles the use case well enough. [Nicholas Seckar]
|
977
982
|
|
978
983
|
Enumerable#first_match was like detect, but instead of returning the matching element, the yielded value returned. For example:
|
979
|
-
|
984
|
+
|
980
985
|
user_xml = adapters(:from => User, :to => Xml).first_match do |adapter|
|
981
986
|
adapter.adapt @user
|
982
987
|
end
|
983
|
-
|
988
|
+
|
984
989
|
But this is just as easily done with:
|
985
|
-
|
990
|
+
|
986
991
|
user_xml = adapters(:from => User, :to => Xml).each do
|
987
992
|
break adapter.adapt(@user)
|
988
993
|
end
|
989
|
-
|
990
|
-
* Make Array#in_groups_of just return the grouped collection if a block isn't given. [Marcel Molina Jr.]
|
994
|
+
|
995
|
+
* Make Array#in_groups_of just return the grouped collection if a block isn't given. [Marcel Molina Jr.]
|
991
996
|
|
992
997
|
* Don't destroy a HashWithIndifferentAccess if symbolize_keys! or stringify_keys! is called on it. Closes #5076. [Marcel Molina Jr., guy.naor@famundo.com]
|
993
998
|
|
@@ -999,7 +1004,7 @@ public for compatibility. [Jeremy Kemper]
|
|
999
1004
|
|
1000
1005
|
* Replace Ruby's deprecated append_features in favor of included. [Marcel Molina Jr.]
|
1001
1006
|
|
1002
|
-
* Allow default options in with_options to be overridden. Closes #4480. [murphy@cYcnus.de]
|
1007
|
+
* Allow default options in with_options to be overridden. Closes #4480. [murphy@cYcnus.de]
|
1003
1008
|
|
1004
1009
|
* Added Module#alias_method_chain [Jamis Buck]
|
1005
1010
|
|
@@ -1050,7 +1055,7 @@ approximations and shouldn't be used for critical calculations. [Michael Koziars
|
|
1050
1055
|
* Added Hash#to_xml and Array#to_xml that makes it much easier to produce XML from basic structures [David Heinemeier Hansson]. Examples:
|
1051
1056
|
|
1052
1057
|
{ :name => "David", :street_name => "Paulina", :age => 26, :moved_on => Date.new(2005, 11, 15) }.to_xml
|
1053
|
-
|
1058
|
+
|
1054
1059
|
...returns:
|
1055
1060
|
|
1056
1061
|
<person>
|
@@ -1069,7 +1074,7 @@ approximations and shouldn't be used for critical calculations. [Michael Koziars
|
|
1069
1074
|
|
1070
1075
|
ex.
|
1071
1076
|
|
1072
|
-
latest_transcripts.group_by(&:day).each do |day, transcripts|
|
1077
|
+
latest_transcripts.group_by(&:day).each do |day, transcripts|
|
1073
1078
|
p "#{day} -> #{transcripts.map(&:class) * ', '}"
|
1074
1079
|
end
|
1075
1080
|
"2006-03-01 -> Transcript"
|
@@ -1093,7 +1098,7 @@ approximations and shouldn't be used for critical calculations. [Michael Koziars
|
|
1093
1098
|
|
1094
1099
|
* Add 'around' methods to Logger, to make it easy to log before and after messages for a given block as requested in #3809. [Michael Koziarski] Example:
|
1095
1100
|
|
1096
|
-
logger.around_info("Start rendering component (#{options.inspect}): ",
|
1101
|
+
logger.around_info("Start rendering component (#{options.inspect}): ",
|
1097
1102
|
"\n\nEnd of component rendering") { yield }
|
1098
1103
|
|
1099
1104
|
* Added Time#beginning_of_quarter #3607 [cohen.jeff@gmail.com]
|
@@ -1111,7 +1116,7 @@ approximations and shouldn't be used for critical calculations. [Michael Koziars
|
|
1111
1116
|
delegate :free?, :paying?, :to => :subscription
|
1112
1117
|
delegate :overdue?, :to => "subscription.last_payment"
|
1113
1118
|
end
|
1114
|
-
|
1119
|
+
|
1115
1120
|
account.free? # => account.subscription.free?
|
1116
1121
|
account.overdue? # => account.subscription.last_payment.overdue?
|
1117
1122
|
|
@@ -1126,7 +1131,7 @@ approximations and shouldn't be used for critical calculations. [Michael Koziars
|
|
1126
1131
|
* Add Reloadable::Subclasses which handles the common case where a base class should not be reloaded, but its subclasses should be. [Nicholas Seckar]
|
1127
1132
|
|
1128
1133
|
* Further improvements to reloading code [Nicholas Seckar, Trevor Squires]
|
1129
|
-
|
1134
|
+
|
1130
1135
|
- All classes/modules which include Reloadable can define reloadable? for fine grained control of reloading
|
1131
1136
|
- Class.remove_class uses Module#parent to access the parent module
|
1132
1137
|
- Class.remove_class expanded to handle multiple classes in a single call
|
@@ -1138,7 +1143,7 @@ approximations and shouldn't be used for critical calculations. [Michael Koziars
|
|
1138
1143
|
class Setting
|
1139
1144
|
include Reloadable
|
1140
1145
|
end
|
1141
|
-
|
1146
|
+
|
1142
1147
|
Reloading a class is done by removing its constant which will cause it to be loaded again on the next reference. [David Heinemeier Hansson]
|
1143
1148
|
|
1144
1149
|
* Added auto-loading support for classes in modules, so Conductor::Migration will look for conductor/migration.rb and Conductor::Database::Settings will look for conductor/database/settings.rb [Nicholas Seckar]
|
@@ -1175,7 +1180,7 @@ approximations and shouldn't be used for critical calculations. [Michael Koziars
|
|
1175
1180
|
* Add Symbol#to_proc, which allows for, e.g. [:foo, :bar].map(&:to_s). [Marcel Molina Jr.]
|
1176
1181
|
|
1177
1182
|
* Added the following methods [Marcel Molina Jr., Sam Stephenson]:
|
1178
|
-
* Object#copy_instance_variables_from(object) to copy instance variables from one object to another
|
1183
|
+
* Object#copy_instance_variables_from(object) to copy instance variables from one object to another
|
1179
1184
|
* Object#extended_by to get an instance's included/extended modules
|
1180
1185
|
* Object#extend_with_included_modules_from(object) to extend an instance with the modules from another instance
|
1181
1186
|
|
@@ -1226,7 +1231,7 @@ approximations and shouldn't be used for critical calculations. [Michael Koziars
|
|
1226
1231
|
|
1227
1232
|
*1.2.0* (October 16th, 2005)
|
1228
1233
|
|
1229
|
-
* Update Exception extension to show the first few framework frames in an application trace. [Nicholas Seckar]
|
1234
|
+
* Update Exception extension to show the first few framework frames in an application trace. [Nicholas Seckar]
|
1230
1235
|
|
1231
1236
|
* Added Exception extension to provide support for clean backtraces. [Nicholas Seckar]
|
1232
1237
|
|
@@ -1275,9 +1280,9 @@ approximations and shouldn't be used for critical calculations. [Michael Koziars
|
|
1275
1280
|
Inflector.inflections do |inflect|
|
1276
1281
|
inflect.plural /^(ox)$/i, '\1\2en'
|
1277
1282
|
inflect.singular /^(ox)en/i, '\1'
|
1278
|
-
|
1283
|
+
|
1279
1284
|
inflect.irregular 'octopus', 'octopi'
|
1280
|
-
|
1285
|
+
|
1281
1286
|
inflect.uncountable "equipment"
|
1282
1287
|
end
|
1283
1288
|
|
@@ -1360,9 +1365,9 @@ approximations and shouldn't be used for critical calculations. [Michael Koziars
|
|
1360
1365
|
* Added Object#suppress which allows you to make a saner choice around with exceptions to swallow #980. Example:
|
1361
1366
|
|
1362
1367
|
suppress(ZeroDivisionError) { 1/0 }
|
1363
|
-
|
1368
|
+
|
1364
1369
|
...instead of:
|
1365
|
-
|
1370
|
+
|
1366
1371
|
1/0 rescue nil # BAD, EVIL, DIRTY.
|
1367
1372
|
|
1368
1373
|
|
@@ -1376,7 +1381,7 @@ approximations and shouldn't be used for critical calculations. [Michael Koziars
|
|
1376
1381
|
values << 'baz'
|
1377
1382
|
end
|
1378
1383
|
end
|
1379
|
-
|
1384
|
+
|
1380
1385
|
foo # => ['bar', 'baz']
|
1381
1386
|
|
1382
1387
|
|
@@ -7,7 +7,7 @@ module ActiveSupport
|
|
7
7
|
if defined? ::Base64
|
8
8
|
Base64 = ::Base64
|
9
9
|
else
|
10
|
-
# Base64 provides utility methods for encoding and de-coding binary data
|
10
|
+
# Base64 provides utility methods for encoding and de-coding binary data
|
11
11
|
# using a base 64 representation. A base 64 representation of binary data
|
12
12
|
# consists entirely of printable US-ASCII characters. The Base64 module
|
13
13
|
# is included in Ruby 1.8, but has been removed in Ruby 1.9.
|
@@ -15,7 +15,7 @@ module ActiveSupport
|
|
15
15
|
# Encodes a string to its base 64 representation. Each 60 characters of
|
16
16
|
# output is separated by a newline character.
|
17
17
|
#
|
18
|
-
# ActiveSupport::Base64.encode64("Original unencoded string")
|
18
|
+
# ActiveSupport::Base64.encode64("Original unencoded string")
|
19
19
|
# # => "T3JpZ2luYWwgdW5lbmNvZGVkIHN0cmluZw==\n"
|
20
20
|
def self.encode64(data)
|
21
21
|
[data].pack("m")
|
@@ -23,7 +23,7 @@ module ActiveSupport
|
|
23
23
|
|
24
24
|
# Decodes a base 64 encoded string to its original representation.
|
25
25
|
#
|
26
|
-
# ActiveSupport::Base64.decode64("T3JpZ2luYWwgdW5lbmNvZGVkIHN0cmluZw==")
|
26
|
+
# ActiveSupport::Base64.decode64("T3JpZ2luYWwgdW5lbmNvZGVkIHN0cmluZw==")
|
27
27
|
# # => "Original unencoded string"
|
28
28
|
def self.decode64(data)
|
29
29
|
data.unpack("m").first
|
@@ -3,10 +3,10 @@ require 'active_support/core_ext/hash/keys'
|
|
3
3
|
|
4
4
|
module ActiveSupport
|
5
5
|
module Benchmarkable
|
6
|
-
# Allows you to measure the execution time of a block
|
6
|
+
# Allows you to measure the execution time of a block
|
7
7
|
# in a template and records the result to the log. Wrap this block around
|
8
8
|
# expensive operations or possible bottlenecks to get a time reading
|
9
|
-
# for the operation. For example, let's say you thought your file
|
9
|
+
# for the operation. For example, let's say you thought your file
|
10
10
|
# processing method was taking too long; you could wrap it in a benchmark block.
|
11
11
|
#
|
12
12
|
# <% benchmark "Process data files" do %>
|
@@ -23,7 +23,7 @@ module ActiveSupport
|
|
23
23
|
# <%= lowlevel_files_operation %>
|
24
24
|
# <% end %>
|
25
25
|
#
|
26
|
-
# Finally, you can pass true as the third argument to silence all log activity
|
26
|
+
# Finally, you can pass true as the third argument to silence all log activity
|
27
27
|
# inside the block. This is great for boiling down a noisy block to just a single statement:
|
28
28
|
#
|
29
29
|
# <% benchmark "Process data files", :level => :info, :silence => true do %>
|
data/lib/active_support/cache.rb
CHANGED
@@ -19,8 +19,6 @@ module ActiveSupport
|
|
19
19
|
autoload :SynchronizedMemoryStore, 'active_support/cache/synchronized_memory_store'
|
20
20
|
autoload :CompressedMemCacheStore, 'active_support/cache/compressed_mem_cache_store'
|
21
21
|
|
22
|
-
EMPTY_OPTIONS = {}.freeze
|
23
|
-
|
24
22
|
# These options mean something to all cache implementations. Individual cache
|
25
23
|
# implementations may support additional options.
|
26
24
|
UNIVERSAL_OPTIONS = [:namespace, :compress, :compress_threshold, :expires_in, :race_condition_ttl]
|
@@ -129,13 +127,6 @@ module ActiveSupport
|
|
129
127
|
# cache.namespace = lambda { @last_mod_time } # Set the namespace to a variable
|
130
128
|
# @last_mod_time = Time.now # Invalidate the entire cache by changing namespace
|
131
129
|
#
|
132
|
-
# All caches support auto expiring content after a specified number of seconds.
|
133
|
-
# To set the cache entry time to live, you can either specify +:expires_in+ as
|
134
|
-
# an option to the constructor to have it affect all entries or to the +fetch+
|
135
|
-
# or +write+ methods for just one entry.
|
136
|
-
#
|
137
|
-
# cache = ActiveSupport::Cache::MemoryStore.new(:expire_in => 5.minutes)
|
138
|
-
# cache.write(key, value, :expire_in => 1.minute) # Set a lower value for one entry
|
139
130
|
#
|
140
131
|
# Caches can also store values in a compressed format to save space and reduce
|
141
132
|
# time spent sending data. Since there is some overhead, values must be large
|
@@ -147,7 +138,7 @@ module ActiveSupport
|
|
147
138
|
|
148
139
|
cattr_accessor :logger, :instance_writer => true
|
149
140
|
|
150
|
-
attr_reader :silence
|
141
|
+
attr_reader :silence, :options
|
151
142
|
alias :silence? :silence
|
152
143
|
|
153
144
|
# Create a new cache. The options will be passed to any write method calls except
|
@@ -156,11 +147,6 @@ module ActiveSupport
|
|
156
147
|
@options = options ? options.dup : {}
|
157
148
|
end
|
158
149
|
|
159
|
-
# Get the default options set when the cache was created.
|
160
|
-
def options
|
161
|
-
@options ||= {}
|
162
|
-
end
|
163
|
-
|
164
150
|
# Silence the logger.
|
165
151
|
def silence!
|
166
152
|
@silence = true
|
@@ -175,7 +161,7 @@ module ActiveSupport
|
|
175
161
|
@silence = previous_silence
|
176
162
|
end
|
177
163
|
|
178
|
-
# Set to true if cache stores should be instrumented.
|
164
|
+
# Set to true if cache stores should be instrumented. Default is false.
|
179
165
|
def self.instrument=(boolean)
|
180
166
|
Thread.current[:instrument_cache_store] = boolean
|
181
167
|
end
|
@@ -187,7 +173,7 @@ module ActiveSupport
|
|
187
173
|
# Fetches data from the cache, using the given key. If there is data in
|
188
174
|
# the cache with the given key, then that data is returned.
|
189
175
|
#
|
190
|
-
# If there is no such data in the cache (a cache miss occurred),
|
176
|
+
# If there is no such data in the cache (a cache miss occurred),
|
191
177
|
# then nil will be returned. However, if a block has been passed, then
|
192
178
|
# that block will be run in the event of a cache miss. The return value
|
193
179
|
# of the block will be written to the cache under the given cache key,
|
@@ -211,23 +197,30 @@ module ActiveSupport
|
|
211
197
|
# Setting <tt>:compress</tt> will store a large cache entry set by the call
|
212
198
|
# in a compressed format.
|
213
199
|
#
|
214
|
-
# Setting <tt>:expires_in</tt> will set an expiration time on the cache
|
215
|
-
# entry if it is set by call.
|
216
200
|
#
|
217
|
-
# Setting <tt>:
|
218
|
-
#
|
219
|
-
#
|
220
|
-
#
|
221
|
-
# future time of the entry in the cache will be updated to that many seconds
|
222
|
-
# in the and the block will be evaluated and written to the cache.
|
201
|
+
# Setting <tt>:expires_in</tt> will set an expiration time on the cache. All caches
|
202
|
+
# support auto expiring content after a specified number of seconds. This value can
|
203
|
+
# be specified as an option to the construction in which call all entries will be
|
204
|
+
# affected. Or it can be supplied to the +fetch+ or +write+ method for just one entry.
|
223
205
|
#
|
224
|
-
#
|
225
|
-
#
|
226
|
-
#
|
227
|
-
#
|
228
|
-
#
|
229
|
-
#
|
230
|
-
#
|
206
|
+
# cache = ActiveSupport::Cache::MemoryStore.new(:expire_in => 5.minutes)
|
207
|
+
# cache.write(key, value, :expire_in => 1.minute) # Set a lower value for one entry
|
208
|
+
#
|
209
|
+
# Setting <tt>:race_condition_ttl</tt> is very useful in situations where a cache entry
|
210
|
+
# is used very frequently unver heavy load. If a cache expires and due to heavy load
|
211
|
+
# seven different processes will try to read data natively and then they all will try to
|
212
|
+
# write to cache. To avoid that case the first process to find an expired cache entry will
|
213
|
+
# bump the cache expiration time by the value set in <tt>:race_condition_ttl</tt>. Yes
|
214
|
+
# this process is extending the time for a stale value by another few seconds. Because
|
215
|
+
# of extended life of the previous cache, other processes will continue to use slightly
|
216
|
+
# stale data for a just a big longer. In the meantime that first process will go ahead
|
217
|
+
# and will write into cache the new value. After that all the processes will start
|
218
|
+
# getting new value. The key is to keep <tt>:race_condition_ttl</tt> small.
|
219
|
+
#
|
220
|
+
# If the process regenerating the entry errors out, the entry will be regenerated
|
221
|
+
# after the specified number of seconds. Also note that the life of stale cache is
|
222
|
+
# extended only if it expired recently. Otherwise a new value is generated and
|
223
|
+
# <tt>:race_condition_ttl</tt> does not play any role.
|
231
224
|
#
|
232
225
|
# # Set all values to expire after one minute.
|
233
226
|
# cache = ActiveSupport::Cache::MemoryCache.new(:expires_in => 1.minute)
|
@@ -252,6 +245,7 @@ module ActiveSupport
|
|
252
245
|
#
|
253
246
|
# # val_1 => "new value 1"
|
254
247
|
# # val_2 => "original value"
|
248
|
+
# # sleep 10 # First thread extend the life of cache by another 10 seconds
|
255
249
|
# # cache.fetch("foo") => "new value 1"
|
256
250
|
#
|
257
251
|
# Other options will be handled by the specific cache store implementation.
|
@@ -353,11 +347,9 @@ module ActiveSupport
|
|
353
347
|
results
|
354
348
|
end
|
355
349
|
|
356
|
-
# Writes the
|
350
|
+
# Writes the value to the cache, with the key.
|
357
351
|
#
|
358
|
-
#
|
359
|
-
# The specific cache store implementation will decide what to do with
|
360
|
-
# +options+.
|
352
|
+
# Options are passed to the underlying cache implementation.
|
361
353
|
def write(name, value, options = nil)
|
362
354
|
options = merged_options(options)
|
363
355
|
instrument(:write, name, options) do |payload|
|
@@ -366,7 +358,7 @@ module ActiveSupport
|
|
366
358
|
end
|
367
359
|
end
|
368
360
|
|
369
|
-
#
|
361
|
+
# Deletes an entry in the cache. Returns +true+ if an entry is deleted.
|
370
362
|
#
|
371
363
|
# Options are passed to the underlying cache implementation.
|
372
364
|
def delete(name, options = nil)
|
@@ -376,7 +368,7 @@ module ActiveSupport
|
|
376
368
|
end
|
377
369
|
end
|
378
370
|
|
379
|
-
# Return true if the cache contains an entry
|
371
|
+
# Return true if the cache contains an entry for the given key.
|
380
372
|
#
|
381
373
|
# Options are passed to the underlying cache implementation.
|
382
374
|
def exist?(name, options = nil)
|
@@ -391,11 +383,11 @@ module ActiveSupport
|
|
391
383
|
end
|
392
384
|
end
|
393
385
|
|
394
|
-
# Delete all entries
|
386
|
+
# Delete all entries with keys matching the pattern.
|
395
387
|
#
|
396
388
|
# Options are passed to the underlying cache implementation.
|
397
389
|
#
|
398
|
-
#
|
390
|
+
# All implementations may not support this method.
|
399
391
|
def delete_matched(matcher, options = nil)
|
400
392
|
raise NotImplementedError.new("#{self.class.name} does not support delete_matched")
|
401
393
|
end
|
@@ -404,7 +396,7 @@ module ActiveSupport
|
|
404
396
|
#
|
405
397
|
# Options are passed to the underlying cache implementation.
|
406
398
|
#
|
407
|
-
#
|
399
|
+
# All implementations may not support this method.
|
408
400
|
def increment(name, amount = 1, options = nil)
|
409
401
|
raise NotImplementedError.new("#{self.class.name} does not support increment")
|
410
402
|
end
|
@@ -413,28 +405,26 @@ module ActiveSupport
|
|
413
405
|
#
|
414
406
|
# Options are passed to the underlying cache implementation.
|
415
407
|
#
|
416
|
-
#
|
408
|
+
# All implementations may not support this method.
|
417
409
|
def decrement(name, amount = 1, options = nil)
|
418
410
|
raise NotImplementedError.new("#{self.class.name} does not support decrement")
|
419
411
|
end
|
420
412
|
|
421
|
-
# Cleanup the cache by removing expired entries.
|
422
|
-
# support this method.
|
413
|
+
# Cleanup the cache by removing expired entries.
|
423
414
|
#
|
424
415
|
# Options are passed to the underlying cache implementation.
|
425
416
|
#
|
426
|
-
#
|
417
|
+
# All implementations may not support this method.
|
427
418
|
def cleanup(options = nil)
|
428
419
|
raise NotImplementedError.new("#{self.class.name} does not support cleanup")
|
429
420
|
end
|
430
421
|
|
431
|
-
# Clear the entire cache.
|
432
|
-
#
|
433
|
-
# if you are using a shared cache.
|
422
|
+
# Clear the entire cache. Be careful with this method since it could
|
423
|
+
# affect other processes if shared cache is being used.
|
434
424
|
#
|
435
425
|
# Options are passed to the underlying cache implementation.
|
436
426
|
#
|
437
|
-
#
|
427
|
+
# All implementations may not support this method.
|
438
428
|
def clear(options = nil)
|
439
429
|
raise NotImplementedError.new("#{self.class.name} does not support clear")
|
440
430
|
end
|
@@ -483,9 +473,9 @@ module ActiveSupport
|
|
483
473
|
end
|
484
474
|
end
|
485
475
|
|
486
|
-
# Expand
|
487
|
-
#
|
488
|
-
# Hash,
|
476
|
+
# Expand key to be a consistent string value. Invoke +cache_key+ if
|
477
|
+
# object responds to +cache_key+. Otherwise, to_param method will be
|
478
|
+
# called. If the key is a Hash, then keys will be sorted alphabetically.
|
489
479
|
def expanded_key(key) # :nodoc:
|
490
480
|
if key.respond_to?(:cache_key)
|
491
481
|
key = key.cache_key.to_s
|
@@ -502,7 +492,7 @@ module ActiveSupport
|
|
502
492
|
end
|
503
493
|
end
|
504
494
|
|
505
|
-
# Prefix a key with the namespace.
|
495
|
+
# Prefix a key with the namespace. Namespace and key will be delimited with a colon.
|
506
496
|
def namespaced_key(key, options)
|
507
497
|
key = expanded_key(key)
|
508
498
|
namespace = options[:namespace] if options
|
@@ -599,7 +589,7 @@ module ActiveSupport
|
|
599
589
|
end
|
600
590
|
end
|
601
591
|
|
602
|
-
# Set a new time
|
592
|
+
# Set a new time when the entry will expire.
|
603
593
|
def expires_at=(time)
|
604
594
|
if time
|
605
595
|
@expires_in = time.to_f - @created_at
|
@@ -608,12 +598,12 @@ module ActiveSupport
|
|
608
598
|
end
|
609
599
|
end
|
610
600
|
|
611
|
-
# Seconds since the epoch when the
|
601
|
+
# Seconds since the epoch when the entry will expire.
|
612
602
|
def expires_at
|
613
603
|
@expires_in ? @created_at + @expires_in : nil
|
614
604
|
end
|
615
605
|
|
616
|
-
#
|
606
|
+
# Returns the size of the cached value. This could be less than value.size
|
617
607
|
# if the data is compressed.
|
618
608
|
def size
|
619
609
|
if @value.nil?
|