activesupport 2.2.3 → 2.3.2
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 +128 -89
- data/lib/active_support.rb +31 -33
- data/lib/active_support/backtrace_cleaner.rb +72 -0
- data/lib/active_support/buffered_logger.rb +9 -7
- data/lib/active_support/cache.rb +13 -8
- data/lib/active_support/cache/drb_store.rb +2 -3
- data/lib/active_support/cache/mem_cache_store.rb +6 -1
- data/lib/active_support/cache/strategy/local_cache.rb +104 -0
- data/lib/active_support/callbacks.rb +20 -21
- data/lib/active_support/core_ext.rb +1 -1
- data/lib/active_support/core_ext/array.rb +2 -0
- data/lib/active_support/core_ext/array/conversions.rb +26 -13
- data/lib/active_support/core_ext/array/wrapper.rb +24 -0
- data/lib/active_support/core_ext/benchmark.rb +13 -6
- data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +14 -5
- data/lib/active_support/core_ext/class/attribute_accessors.rb +24 -24
- data/lib/active_support/core_ext/class/delegating_attributes.rb +20 -19
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +34 -34
- data/lib/active_support/core_ext/date/conversions.rb +3 -3
- data/lib/active_support/core_ext/date_time/conversions.rb +1 -1
- data/lib/active_support/core_ext/enumerable.rb +9 -0
- data/lib/active_support/core_ext/exception.rb +12 -8
- data/lib/active_support/core_ext/file/atomic.rb +2 -2
- data/lib/active_support/core_ext/hash/conversions.rb +32 -54
- data/lib/active_support/core_ext/hash/indifferent_access.rb +6 -0
- data/lib/active_support/core_ext/hash/keys.rb +1 -1
- data/lib/active_support/core_ext/hash/slice.rb +8 -1
- data/lib/active_support/core_ext/logger.rb +8 -6
- data/lib/active_support/core_ext/module/aliasing.rb +3 -3
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +4 -4
- data/lib/active_support/core_ext/module/attribute_accessors.rb +24 -24
- data/lib/active_support/core_ext/module/delegation.rb +29 -3
- data/lib/active_support/core_ext/module/synchronization.rb +5 -5
- data/lib/active_support/core_ext/object/conversions.rb +2 -1
- data/lib/active_support/core_ext/object/misc.rb +16 -0
- data/lib/active_support/core_ext/range/conversions.rb +1 -1
- data/lib/active_support/core_ext/rexml.rb +29 -24
- data/lib/active_support/core_ext/string/inflections.rb +3 -3
- data/lib/active_support/core_ext/time/calculations.rb +1 -2
- data/lib/active_support/core_ext/time/conversions.rb +1 -1
- data/lib/active_support/core_ext/try.rb +36 -0
- data/lib/active_support/dependencies.rb +18 -14
- data/lib/active_support/deprecation.rb +10 -57
- data/lib/active_support/duration.rb +3 -1
- data/lib/active_support/inflections.rb +1 -0
- data/lib/active_support/inflector.rb +16 -7
- data/lib/active_support/json/decoding.rb +21 -3
- data/lib/active_support/json/encoders/date.rb +1 -1
- data/lib/active_support/json/encoders/date_time.rb +1 -1
- data/lib/active_support/json/encoders/hash.rb +10 -11
- data/lib/active_support/json/encoders/time.rb +1 -1
- data/lib/active_support/json/encoding.rb +23 -29
- data/lib/active_support/locale/en.yml +3 -2
- data/lib/active_support/memoizable.rb +61 -43
- data/lib/active_support/message_encryptor.rb +70 -0
- data/lib/active_support/message_verifier.rb +46 -0
- data/lib/active_support/multibyte.rb +6 -30
- data/lib/active_support/multibyte/chars.rb +30 -9
- data/lib/active_support/multibyte/unicode_database.rb +4 -4
- data/lib/active_support/option_merger.rb +7 -1
- data/lib/active_support/ordered_hash.rb +75 -27
- data/lib/active_support/secure_random.rb +8 -6
- data/lib/active_support/test_case.rb +32 -17
- data/lib/active_support/testing/{core_ext/test/unit/assertions.rb → assertions.rb} +13 -20
- data/lib/active_support/testing/declarative.rb +21 -0
- data/lib/active_support/testing/deprecation.rb +55 -0
- data/lib/active_support/testing/performance.rb +1 -1
- data/lib/active_support/testing/setup_and_teardown.rb +57 -86
- data/lib/active_support/time_with_zone.rb +8 -6
- data/lib/active_support/values/time_zone.rb +1 -0
- data/lib/active_support/vendor.rb +6 -11
- data/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE +20 -0
- data/lib/active_support/vendor/i18n-0.1.3/README.textile +20 -0
- data/lib/active_support/vendor/i18n-0.1.3/Rakefile +5 -0
- data/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec +27 -0
- data/lib/active_support/vendor/{i18n-0.0.1 → i18n-0.1.3/lib}/i18n.rb +42 -37
- data/lib/active_support/vendor/{i18n-0.0.1 → i18n-0.1.3/lib}/i18n/backend/simple.rb +37 -39
- data/lib/active_support/vendor/{i18n-0.0.1 → i18n-0.1.3/lib}/i18n/exceptions.rb +3 -3
- data/lib/active_support/vendor/i18n-0.1.3/test/all.rb +5 -0
- data/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb +100 -0
- data/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb +125 -0
- data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb +1 -0
- data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml +3 -0
- data/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb +568 -0
- data/lib/active_support/vendor/{memcache-client-1.5.1 → memcache-client-1.6.5}/memcache.rb +381 -295
- data/lib/active_support/version.rb +2 -2
- data/lib/active_support/xml_mini.rb +31 -0
- data/lib/active_support/xml_mini/libxml.rb +133 -0
- data/lib/active_support/xml_mini/nokogiri.rb +77 -0
- data/lib/active_support/xml_mini/rexml.rb +108 -0
- metadata +85 -14
- data/lib/active_support/multibyte/utils.rb +0 -61
- data/lib/active_support/testing/core_ext/test.rb +0 -6
- data/lib/active_support/vendor/xml-simple-1.0.11/xmlsimple.rb +0 -1021
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'tempfile'
|
2
|
-
|
3
1
|
module ActiveSupport #:nodoc:
|
4
2
|
module CoreExtensions #:nodoc:
|
5
3
|
module File #:nodoc:
|
@@ -18,6 +16,8 @@ module ActiveSupport #:nodoc:
|
|
18
16
|
# file.write("hello")
|
19
17
|
# end
|
20
18
|
def atomic_write(file_name, temp_dir = Dir.tmpdir)
|
19
|
+
require 'tempfile' unless defined?(Tempfile)
|
20
|
+
|
21
21
|
temp_file = Tempfile.new(basename(file_name), temp_dir)
|
22
22
|
yield temp_file
|
23
23
|
temp_file.close
|
@@ -1,47 +1,22 @@
|
|
1
1
|
require 'date'
|
2
|
-
require 'cgi'
|
3
|
-
require 'builder'
|
4
|
-
require 'xmlsimple'
|
5
|
-
|
6
|
-
# Locked down XmlSimple#xml_in_string
|
7
|
-
class XmlSimple
|
8
|
-
# Same as xml_in but doesn't try to smartly shoot itself in the foot.
|
9
|
-
def xml_in_string(string, options = nil)
|
10
|
-
handle_options('in', options)
|
11
|
-
|
12
|
-
@doc = parse(string)
|
13
|
-
result = collapse(@doc.root)
|
14
|
-
|
15
|
-
if @options['keeproot']
|
16
|
-
merge({}, @doc.root.name, result)
|
17
|
-
else
|
18
|
-
result
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.xml_in_string(string, options = nil)
|
23
|
-
new.xml_in_string(string, options)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
# This module exists to decorate files deserialized using Hash.from_xml with
|
28
|
-
# the <tt>original_filename</tt> and <tt>content_type</tt> methods.
|
29
|
-
module FileLike #:nodoc:
|
30
|
-
attr_writer :original_filename, :content_type
|
31
|
-
|
32
|
-
def original_filename
|
33
|
-
@original_filename || 'untitled'
|
34
|
-
end
|
35
|
-
|
36
|
-
def content_type
|
37
|
-
@content_type || 'application/octet-stream'
|
38
|
-
end
|
39
|
-
end
|
40
2
|
|
41
3
|
module ActiveSupport #:nodoc:
|
42
4
|
module CoreExtensions #:nodoc:
|
43
5
|
module Hash #:nodoc:
|
44
6
|
module Conversions
|
7
|
+
# This module exists to decorate files deserialized using Hash.from_xml with
|
8
|
+
# the <tt>original_filename</tt> and <tt>content_type</tt> methods.
|
9
|
+
module FileLike #:nodoc:
|
10
|
+
attr_writer :original_filename, :content_type
|
11
|
+
|
12
|
+
def original_filename
|
13
|
+
@original_filename || 'untitled'
|
14
|
+
end
|
15
|
+
|
16
|
+
def content_type
|
17
|
+
@content_type || 'application/octet-stream'
|
18
|
+
end
|
19
|
+
end
|
45
20
|
|
46
21
|
XML_TYPE_NAMES = {
|
47
22
|
"Symbol" => "symbol",
|
@@ -49,11 +24,12 @@ module ActiveSupport #:nodoc:
|
|
49
24
|
"Bignum" => "integer",
|
50
25
|
"BigDecimal" => "decimal",
|
51
26
|
"Float" => "float",
|
27
|
+
"TrueClass" => "boolean",
|
28
|
+
"FalseClass" => "boolean",
|
52
29
|
"Date" => "date",
|
53
30
|
"DateTime" => "datetime",
|
54
31
|
"Time" => "datetime",
|
55
|
-
"
|
56
|
-
"FalseClass" => "boolean"
|
32
|
+
"ActiveSupport::TimeWithZone" => "datetime"
|
57
33
|
} unless defined?(XML_TYPE_NAMES)
|
58
34
|
|
59
35
|
XML_FORMATTING = {
|
@@ -100,7 +76,7 @@ module ActiveSupport #:nodoc:
|
|
100
76
|
# Converts a hash into a string suitable for use as a URL query string. An optional <tt>namespace</tt> can be
|
101
77
|
# passed to enclose the param names (see example below).
|
102
78
|
#
|
103
|
-
# ====
|
79
|
+
# ==== Examples
|
104
80
|
# { :name => 'David', :nationality => 'Danish' }.to_query # => "name=David&nationality=Danish"
|
105
81
|
#
|
106
82
|
# { :name => 'David', :nationality => 'Danish' }.to_query('user') # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
|
@@ -113,12 +89,13 @@ module ActiveSupport #:nodoc:
|
|
113
89
|
alias_method :to_param, :to_query
|
114
90
|
|
115
91
|
def to_xml(options = {})
|
92
|
+
require 'builder' unless defined?(Builder)
|
93
|
+
|
116
94
|
options[:indent] ||= 2
|
117
95
|
options.reverse_merge!({ :builder => Builder::XmlMarkup.new(:indent => options[:indent]),
|
118
96
|
:root => "hash" })
|
119
97
|
options[:builder].instruct! unless options.delete(:skip_instruct)
|
120
|
-
|
121
|
-
root = dasherize ? options[:root].to_s.dasherize : options[:root].to_s
|
98
|
+
root = rename_key(options[:root].to_s, options)
|
122
99
|
|
123
100
|
options[:builder].__send__(:method_missing, root) do
|
124
101
|
each do |key, value|
|
@@ -145,7 +122,7 @@ module ActiveSupport #:nodoc:
|
|
145
122
|
else
|
146
123
|
type_name = XML_TYPE_NAMES[value.class.name]
|
147
124
|
|
148
|
-
key =
|
125
|
+
key = rename_key(key.to_s, options)
|
149
126
|
|
150
127
|
attributes = options[:skip_types] || value.nil? || type_name.nil? ? { } : { :type => type_name }
|
151
128
|
if value.nil?
|
@@ -165,15 +142,16 @@ module ActiveSupport #:nodoc:
|
|
165
142
|
|
166
143
|
end
|
167
144
|
|
145
|
+
def rename_key(key, options = {})
|
146
|
+
camelize = options.has_key?(:camelize) && options[:camelize]
|
147
|
+
dasherize = !options.has_key?(:dasherize) || options[:dasherize]
|
148
|
+
key = key.camelize if camelize
|
149
|
+
dasherize ? key.dasherize : key
|
150
|
+
end
|
151
|
+
|
168
152
|
module ClassMethods
|
169
153
|
def from_xml(xml)
|
170
|
-
|
171
|
-
typecast_xml_value(undasherize_keys(XmlSimple.xml_in_string(xml,
|
172
|
-
'forcearray' => false,
|
173
|
-
'forcecontent' => true,
|
174
|
-
'keeproot' => true,
|
175
|
-
'contentkey' => '__content__')
|
176
|
-
))
|
154
|
+
typecast_xml_value(unrename_keys(XmlMini.parse(xml)))
|
177
155
|
end
|
178
156
|
|
179
157
|
private
|
@@ -239,15 +217,15 @@ module ActiveSupport #:nodoc:
|
|
239
217
|
end
|
240
218
|
end
|
241
219
|
|
242
|
-
def
|
220
|
+
def unrename_keys(params)
|
243
221
|
case params.class.to_s
|
244
222
|
when "Hash"
|
245
223
|
params.inject({}) do |h,(k,v)|
|
246
|
-
h[k.to_s.tr("-", "_")] =
|
224
|
+
h[k.to_s.underscore.tr("-", "_")] = unrename_keys(v)
|
247
225
|
h
|
248
226
|
end
|
249
227
|
when "Array"
|
250
|
-
params.map { |v|
|
228
|
+
params.map { |v| unrename_keys(v) }
|
251
229
|
else
|
252
230
|
params
|
253
231
|
end
|
@@ -91,6 +91,12 @@ class HashWithIndifferentAccess < Hash
|
|
91
91
|
self.dup.update(hash)
|
92
92
|
end
|
93
93
|
|
94
|
+
# Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
|
95
|
+
# This overloaded definition prevents returning a regular hash, if reverse_merge is called on a HashWithDifferentAccess.
|
96
|
+
def reverse_merge(other_hash)
|
97
|
+
super other_hash.with_indifferent_access
|
98
|
+
end
|
99
|
+
|
94
100
|
# Removes a specified key from the hash.
|
95
101
|
def delete(key)
|
96
102
|
super(convert_key(key))
|
@@ -38,7 +38,7 @@ module ActiveSupport #:nodoc:
|
|
38
38
|
# Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbols
|
39
39
|
# as keys, this will fail.
|
40
40
|
#
|
41
|
-
# ==== Examples
|
41
|
+
# ==== Examples
|
42
42
|
# { :name => "Rob", :years => "28" }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key(s): years"
|
43
43
|
# { :name => "Rob", :age => "28" }.assert_valid_keys("name", "age") # => raises "ArgumentError: Unknown key(s): name, age"
|
44
44
|
# { :name => "Rob", :age => "28" }.assert_valid_keys(:name, :age) # => passes, raises nothing
|
@@ -24,10 +24,17 @@ module ActiveSupport #:nodoc:
|
|
24
24
|
end
|
25
25
|
|
26
26
|
# Replaces the hash with only the given keys.
|
27
|
+
# Returns a hash contained the removed key/value pairs
|
28
|
+
# {:a => 1, :b => 2, :c => 3, :d => 4}.slice!(:a, :b) # => {:c => 3, :d =>4}
|
27
29
|
def slice!(*keys)
|
28
|
-
|
30
|
+
keys = keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
|
31
|
+
omit = slice(*self.keys - keys)
|
32
|
+
hash = slice(*keys)
|
33
|
+
replace(hash)
|
34
|
+
omit
|
29
35
|
end
|
30
36
|
end
|
31
37
|
end
|
32
38
|
end
|
33
39
|
end
|
40
|
+
|
@@ -3,12 +3,12 @@
|
|
3
3
|
class Logger
|
4
4
|
def self.define_around_helper(level)
|
5
5
|
module_eval <<-end_eval
|
6
|
-
def around_#{level}(before_message, after_message, &block)
|
7
|
-
self.#{level}(before_message)
|
8
|
-
return_value = block.call(self)
|
9
|
-
self.#{level}(after_message)
|
10
|
-
return return_value
|
11
|
-
end
|
6
|
+
def around_#{level}(before_message, after_message, &block) # def around_debug(before_message, after_message, &block)
|
7
|
+
self.#{level}(before_message) # self.debug(before_message)
|
8
|
+
return_value = block.call(self) # return_value = block.call(self)
|
9
|
+
self.#{level}(after_message) # self.debug(after_message)
|
10
|
+
return return_value # return return_value
|
11
|
+
end # end
|
12
12
|
end_eval
|
13
13
|
end
|
14
14
|
[:debug, :info, :error, :fatal].each {|level| define_around_helper(level) }
|
@@ -30,6 +30,8 @@ require 'logger'
|
|
30
30
|
#
|
31
31
|
# Note: This logger is deprecated in favor of ActiveSupport::BufferedLogger
|
32
32
|
class Logger
|
33
|
+
##
|
34
|
+
# :singleton-method:
|
33
35
|
# Set to false to disable the silencer
|
34
36
|
cattr_accessor :silencer
|
35
37
|
self.silencer = true
|
@@ -64,9 +64,9 @@ module ActiveSupport
|
|
64
64
|
# e.title # => "Megastars"
|
65
65
|
def alias_attribute(new_name, old_name)
|
66
66
|
module_eval <<-STR, __FILE__, __LINE__+1
|
67
|
-
def #{new_name}; self.#{old_name}; end
|
68
|
-
def #{new_name}?; self.#{old_name}?; end
|
69
|
-
def #{new_name}=(v); self.#{old_name} = v; end
|
67
|
+
def #{new_name}; self.#{old_name}; end # def subject; self.title; end
|
68
|
+
def #{new_name}?; self.#{old_name}?; end # def subject?; self.title?; end
|
69
|
+
def #{new_name}=(v); self.#{old_name} = v; end # def subject=(v); self.title = v; end
|
70
70
|
STR
|
71
71
|
end
|
72
72
|
end
|
@@ -22,10 +22,10 @@ class Module
|
|
22
22
|
raise 'Default value or block required' unless !default.nil? || block
|
23
23
|
define_method(sym, block_given? ? block : Proc.new { default })
|
24
24
|
module_eval(<<-EVAL, __FILE__, __LINE__)
|
25
|
-
def #{sym}=(value)
|
26
|
-
class << self; attr_reader :#{sym} end
|
27
|
-
@#{sym} = value
|
28
|
-
end
|
25
|
+
def #{sym}=(value) # def age=(value)
|
26
|
+
class << self; attr_reader :#{sym} end # class << self; attr_reader :age end
|
27
|
+
@#{sym} = value # @age = value
|
28
|
+
end # end
|
29
29
|
EVAL
|
30
30
|
end
|
31
31
|
end
|
@@ -15,17 +15,17 @@ class Module
|
|
15
15
|
syms.each do |sym|
|
16
16
|
next if sym.is_a?(Hash)
|
17
17
|
class_eval(<<-EOS, __FILE__, __LINE__)
|
18
|
-
unless defined? @@#{sym}
|
19
|
-
@@#{sym} = nil
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.#{sym}
|
23
|
-
@@#{sym}
|
24
|
-
end
|
25
|
-
|
26
|
-
def #{sym}
|
27
|
-
@@#{sym}
|
28
|
-
end
|
18
|
+
unless defined? @@#{sym} # unless defined? @@pagination_options
|
19
|
+
@@#{sym} = nil # @@pagination_options = nil
|
20
|
+
end # end
|
21
|
+
#
|
22
|
+
def self.#{sym} # def self.pagination_options
|
23
|
+
@@#{sym} # @@pagination_options
|
24
|
+
end # end
|
25
|
+
#
|
26
|
+
def #{sym} # def pagination_options
|
27
|
+
@@#{sym} # @@pagination_options
|
28
|
+
end # end
|
29
29
|
EOS
|
30
30
|
end
|
31
31
|
end
|
@@ -34,19 +34,19 @@ class Module
|
|
34
34
|
options = syms.extract_options!
|
35
35
|
syms.each do |sym|
|
36
36
|
class_eval(<<-EOS, __FILE__, __LINE__)
|
37
|
-
unless defined? @@#{sym}
|
38
|
-
@@#{sym} = nil
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.#{sym}=(obj)
|
42
|
-
@@#{sym} = obj
|
43
|
-
end
|
44
|
-
|
45
|
-
#{"
|
46
|
-
def #{sym}=(obj)
|
47
|
-
@@#{sym} = obj
|
48
|
-
end
|
49
|
-
" unless options[:instance_writer] == false }
|
37
|
+
unless defined? @@#{sym} # unless defined? @@pagination_options
|
38
|
+
@@#{sym} = nil # @@pagination_options = nil
|
39
|
+
end # end
|
40
|
+
#
|
41
|
+
def self.#{sym}=(obj) # def self.pagination_options=(obj)
|
42
|
+
@@#{sym} = obj # @@pagination_options = obj
|
43
|
+
end # end
|
44
|
+
#
|
45
|
+
#{" #
|
46
|
+
def #{sym}=(obj) # def pagination_options=(obj)
|
47
|
+
@@#{sym} = obj # @@pagination_options = obj
|
48
|
+
end # end
|
49
|
+
" unless options[:instance_writer] == false } # # instance writer above is generated unless options[:instance_writer] == false
|
50
50
|
EOS
|
51
51
|
end
|
52
52
|
end
|
@@ -72,6 +72,30 @@ class Module
|
|
72
72
|
# invoice.customer_name # => "John Doe"
|
73
73
|
# invoice.customer_address # => "Vimmersvej 13"
|
74
74
|
#
|
75
|
+
# If the object to which you delegate can be nil, you may want to use the
|
76
|
+
# :allow_nil option. In that case, it returns nil instead of raising a
|
77
|
+
# NoMethodError exception:
|
78
|
+
#
|
79
|
+
# class Foo
|
80
|
+
# attr_accessor :bar
|
81
|
+
# def initialize(bar = nil)
|
82
|
+
# @bar = bar
|
83
|
+
# end
|
84
|
+
# delegate :zoo, :to => :bar
|
85
|
+
# end
|
86
|
+
#
|
87
|
+
# Foo.new.zoo # raises NoMethodError exception (you called nil.zoo)
|
88
|
+
#
|
89
|
+
# class Foo
|
90
|
+
# attr_accessor :bar
|
91
|
+
# def initialize(bar = nil)
|
92
|
+
# @bar = bar
|
93
|
+
# end
|
94
|
+
# delegate :zoo, :to => :bar, :allow_nil => true
|
95
|
+
# end
|
96
|
+
#
|
97
|
+
# Foo.new.zoo # returns nil
|
98
|
+
#
|
75
99
|
def delegate(*methods)
|
76
100
|
options = methods.pop
|
77
101
|
unless options.is_a?(Hash) && to = options[:to]
|
@@ -84,11 +108,13 @@ class Module
|
|
84
108
|
|
85
109
|
prefix = options[:prefix] && "#{options[:prefix] == true ? to : options[:prefix]}_"
|
86
110
|
|
111
|
+
allow_nil = options[:allow_nil] && "#{to} && "
|
112
|
+
|
87
113
|
methods.each do |method|
|
88
114
|
module_eval(<<-EOS, "(__DELEGATION__)", 1)
|
89
|
-
def #{prefix}#{method}(*args, &block)
|
90
|
-
#{to}.__send__(#{method.inspect}, *args, &block)
|
91
|
-
end
|
115
|
+
def #{prefix}#{method}(*args, &block) # def customer_name(*args, &block)
|
116
|
+
#{allow_nil}#{to}.__send__(#{method.inspect}, *args, &block) # client && client.__send__(:name, *args, &block)
|
117
|
+
end # end
|
92
118
|
EOS
|
93
119
|
end
|
94
120
|
end
|
@@ -26,11 +26,11 @@ class Module
|
|
26
26
|
end
|
27
27
|
|
28
28
|
module_eval(<<-EOS, __FILE__, __LINE__)
|
29
|
-
def #{aliased_method}_with_synchronization#{punctuation}(*args, &block)
|
30
|
-
#{with}.synchronize do
|
31
|
-
#{aliased_method}_without_synchronization#{punctuation}(*args, &block)
|
32
|
-
end
|
33
|
-
end
|
29
|
+
def #{aliased_method}_with_synchronization#{punctuation}(*args, &block) # def expire_with_synchronization(*args, &block)
|
30
|
+
#{with}.synchronize do # @@lock.synchronize do
|
31
|
+
#{aliased_method}_without_synchronization#{punctuation}(*args, &block) # expire_without_synchronization(*args, &block)
|
32
|
+
end # end
|
33
|
+
end # end
|
34
34
|
EOS
|
35
35
|
|
36
36
|
alias_method_chain method, :synchronization
|
@@ -9,6 +9,7 @@ class Object
|
|
9
9
|
#
|
10
10
|
# Note: This method is defined as a default implementation for all Objects for Hash#to_query to work.
|
11
11
|
def to_query(key)
|
12
|
+
require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
|
12
13
|
"#{CGI.escape(key.to_s)}=#{CGI.escape(to_param.to_s)}"
|
13
14
|
end
|
14
|
-
end
|
15
|
+
end
|
@@ -40,6 +40,21 @@ class Object
|
|
40
40
|
value
|
41
41
|
end
|
42
42
|
|
43
|
+
# Yields <code>x</code> to the block, and then returns <code>x</code>.
|
44
|
+
# The primary purpose of this method is to "tap into" a method chain,
|
45
|
+
# in order to perform operations on intermediate results within the chain.
|
46
|
+
#
|
47
|
+
# (1..10).tap { |x| puts "original: #{x.inspect}" }.to_a.
|
48
|
+
# tap { |x| puts "array: #{x.inspect}" }.
|
49
|
+
# select { |x| x%2 == 0 }.
|
50
|
+
# tap { |x| puts "evens: #{x.inspect}" }.
|
51
|
+
# map { |x| x*x }.
|
52
|
+
# tap { |x| puts "squares: #{x.inspect}" }
|
53
|
+
def tap
|
54
|
+
yield self
|
55
|
+
self
|
56
|
+
end unless Object.respond_to?(:tap)
|
57
|
+
|
43
58
|
# An elegant way to factor duplication out of options passed to a series of
|
44
59
|
# method calls. Each method called in the block, with the block variable as
|
45
60
|
# the receiver, will have its options merged with the default +options+ hash
|
@@ -71,4 +86,5 @@ class Object
|
|
71
86
|
def acts_like?(duck)
|
72
87
|
respond_to? "acts_like_#{duck}?"
|
73
88
|
end
|
89
|
+
|
74
90
|
end
|
@@ -1,34 +1,39 @@
|
|
1
|
-
require 'rexml/document'
|
2
|
-
require 'rexml/entity'
|
3
|
-
|
4
1
|
# Fixes the rexml vulnerability disclosed at:
|
5
2
|
# http://www.ruby-lang.org/en/news/2008/08/23/dos-vulnerability-in-rexml/
|
6
3
|
# This fix is identical to rexml-expansion-fix version 1.0.1
|
4
|
+
require 'rexml/rexml'
|
7
5
|
|
8
6
|
# Earlier versions of rexml defined REXML::Version, newer ones REXML::VERSION
|
9
|
-
unless REXML::
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
7
|
+
unless (defined?(REXML::VERSION) ? REXML::VERSION : REXML::Version) > "3.1.7.2"
|
8
|
+
require 'rexml/document'
|
9
|
+
|
10
|
+
# REXML in 1.8.7 has the patch but didn't update Version from 3.1.7.2.
|
11
|
+
unless REXML::Document.respond_to?(:entity_expansion_limit=)
|
12
|
+
require 'rexml/entity'
|
13
|
+
|
14
|
+
module REXML
|
15
|
+
class Entity < Child
|
16
|
+
undef_method :unnormalized
|
17
|
+
def unnormalized
|
18
|
+
document.record_entity_expansion! if document
|
19
|
+
v = value()
|
20
|
+
return nil if v.nil?
|
21
|
+
@unnormalized = Text::unnormalize(v, parent)
|
22
|
+
@unnormalized
|
23
|
+
end
|
25
24
|
end
|
25
|
+
class Document < Element
|
26
|
+
@@entity_expansion_limit = 10_000
|
27
|
+
def self.entity_expansion_limit= val
|
28
|
+
@@entity_expansion_limit = val
|
29
|
+
end
|
26
30
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
31
|
+
def record_entity_expansion!
|
32
|
+
@number_of_expansions ||= 0
|
33
|
+
@number_of_expansions += 1
|
34
|
+
if @number_of_expansions > @@entity_expansion_limit
|
35
|
+
raise "Number of entity expansions exceeded, processing aborted."
|
36
|
+
end
|
32
37
|
end
|
33
38
|
end
|
34
39
|
end
|