activesupport 3.1.0.beta1 → 3.1.0.rc1
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 +33 -1
- data/README.rdoc +1 -1
- data/lib/active_support.rb +1 -1
- data/lib/active_support/buffered_logger.rb +9 -4
- data/lib/active_support/configurable.rb +9 -6
- data/lib/active_support/core_ext/array/conversions.rb +2 -2
- data/lib/active_support/core_ext/array/random_access.rb +1 -1
- data/lib/active_support/core_ext/array/uniq_by.rb +2 -3
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +0 -2
- data/lib/active_support/core_ext/date/calculations.rb +3 -3
- data/lib/active_support/core_ext/date/conversions.rb +3 -2
- data/lib/active_support/core_ext/date_time/conversions.rb +8 -8
- data/lib/active_support/core_ext/hash/conversions.rb +2 -1
- data/lib/active_support/core_ext/hash/indifferent_access.rb +12 -0
- data/lib/active_support/core_ext/hash/slice.rb +1 -1
- data/lib/active_support/core_ext/integer/inflections.rb +7 -4
- data/lib/active_support/core_ext/kernel/reporting.rb +13 -1
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +1 -0
- data/lib/active_support/core_ext/module/deprecation.rb +0 -2
- data/lib/active_support/core_ext/numeric/time.rb +2 -0
- data/lib/active_support/core_ext/object/blank.rb +3 -3
- data/lib/active_support/core_ext/object/duplicable.rb +2 -0
- data/lib/active_support/core_ext/object/try.rb +2 -0
- data/lib/active_support/core_ext/object/with_options.rb +8 -5
- data/lib/active_support/core_ext/string/behavior.rb +1 -2
- data/lib/active_support/core_ext/string/exclude.rb +1 -1
- data/lib/active_support/core_ext/string/inquiry.rb +1 -1
- data/lib/active_support/core_ext/time/calculations.rb +4 -3
- data/lib/active_support/core_ext/time/marshal.rb +1 -0
- data/lib/active_support/descendants_tracker.rb +9 -7
- data/lib/active_support/duration.rb +1 -0
- data/lib/active_support/hash_with_indifferent_access.rb +12 -4
- data/lib/active_support/inflector/methods.rb +5 -3
- data/lib/active_support/json/encoding.rb +4 -1
- data/lib/active_support/log_subscriber/test_helper.rb +1 -0
- data/lib/active_support/ordered_hash.rb +4 -0
- data/lib/active_support/secure_random.rb +3 -202
- data/lib/active_support/testing/performance.rb +227 -335
- data/lib/active_support/testing/performance/jruby.rb +115 -0
- data/lib/active_support/testing/performance/rubinius.rb +113 -0
- data/lib/active_support/testing/performance/ruby.rb +152 -0
- data/lib/active_support/testing/performance/ruby/mri.rb +59 -0
- data/lib/active_support/testing/performance/ruby/yarv.rb +57 -0
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini.rb +4 -1
- metadata +8 -3
data/CHANGELOG
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
*Rails 3.1.0 (unreleased)*
|
2
2
|
|
3
|
+
* New reporting method Kernel#quietly. [fxn]
|
4
|
+
|
3
5
|
* Add String#inquiry as a convenience method for turning a string into a StringInquirer object [DHH]
|
4
6
|
|
5
7
|
* Add Object#in? to test if an object is included in another object [Prem Sichanugrist, Brian Morearty, John Reitano]
|
@@ -19,14 +21,44 @@ advantage of the new ClassCache.
|
|
19
21
|
|
20
22
|
* Added before_remove_const callback to ActiveSupport::Dependencies.remove_unloadable_constants! [Andrew White]
|
21
23
|
|
22
|
-
*
|
24
|
+
* JSON decoding now uses the multi_json gem which also vendors a json engine called OkJson. The yaml backend has been removed in favor of OkJson as a default engine for 1.8.x, while the built in 1.9.x json implementation will be used by default. [Josh Kalderimis]
|
25
|
+
|
26
|
+
|
27
|
+
*Rails 3.0.7 (April 18, 2011)*
|
28
|
+
|
29
|
+
* Hash.from_xml no longer loses attributes on tags containing only whitespace [André Arko]
|
30
|
+
|
31
|
+
|
32
|
+
*Rails 3.0.6 (April 5, 2011)
|
33
|
+
|
34
|
+
* No changes.
|
35
|
+
|
36
|
+
|
37
|
+
*Rails 3.0.5 (February 26, 2011)*
|
38
|
+
|
39
|
+
* No changes.
|
40
|
+
|
41
|
+
|
42
|
+
*Rails 3.0.4 (February 8, 2011)*
|
43
|
+
|
44
|
+
* No changes.
|
45
|
+
|
46
|
+
|
47
|
+
*Rails 3.0.3 (November 16, 2010)*
|
48
|
+
|
49
|
+
* No changes.
|
50
|
+
|
51
|
+
|
52
|
+
*Rails 3.0.2 (November 15, 2010)*
|
23
53
|
|
24
54
|
* Added before_remove_const callback to ActiveSupport::Dependencies.remove_unloadable_constants! [Andrew White]
|
25
55
|
|
56
|
+
|
26
57
|
*Rails 3.0.1 (October 15, 2010)*
|
27
58
|
|
28
59
|
* No Changes, just a version bump.
|
29
60
|
|
61
|
+
|
30
62
|
*Rails 3.0.0 (August 29, 2010)*
|
31
63
|
|
32
64
|
* Implemented String#strip_heredoc. [fxn]
|
data/README.rdoc
CHANGED
data/lib/active_support.rb
CHANGED
@@ -48,12 +48,17 @@ module ActiveSupport
|
|
48
48
|
if log.respond_to?(:write)
|
49
49
|
@log = log
|
50
50
|
elsif File.exist?(log)
|
51
|
-
@log =
|
52
|
-
@log.sync = true
|
51
|
+
@log = open_log(log, (File::WRONLY | File::APPEND))
|
53
52
|
else
|
54
53
|
FileUtils.mkdir_p(File.dirname(log))
|
55
|
-
@log =
|
56
|
-
|
54
|
+
@log = open_log(log, (File::WRONLY | File::APPEND | File::CREAT))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def open_log(log, mode)
|
59
|
+
open(log, mode).tap do |open_log|
|
60
|
+
open_log.set_encoding(Encoding::BINARY) if open_log.respond_to?(:set_encoding)
|
61
|
+
open_log.sync = true
|
57
62
|
end
|
58
63
|
end
|
59
64
|
|
@@ -2,6 +2,7 @@ require 'active_support/concern'
|
|
2
2
|
require 'active_support/ordered_options'
|
3
3
|
require 'active_support/core_ext/kernel/singleton_class'
|
4
4
|
require 'active_support/core_ext/module/delegation'
|
5
|
+
require 'active_support/core_ext/array/extract_options'
|
5
6
|
|
6
7
|
module ActiveSupport
|
7
8
|
# Configurable provides a <tt>config</tt> method to store and retrieve
|
@@ -51,14 +52,16 @@ module ActiveSupport
|
|
51
52
|
# user.allowed_access # => true
|
52
53
|
#
|
53
54
|
def config_accessor(*names)
|
55
|
+
options = names.extract_options!
|
56
|
+
|
54
57
|
names.each do |name|
|
55
|
-
|
56
|
-
|
57
|
-
def #{name}=(value); config.#{name} = value; end
|
58
|
-
RUBY
|
58
|
+
reader, line = "def #{name}; config.#{name}; end", __LINE__
|
59
|
+
writer, line = "def #{name}=(value); config.#{name} = value; end", __LINE__
|
59
60
|
|
60
|
-
singleton_class.class_eval
|
61
|
-
class_eval
|
61
|
+
singleton_class.class_eval reader, __FILE__, line
|
62
|
+
singleton_class.class_eval writer, __FILE__, line
|
63
|
+
class_eval reader, __FILE__, line unless options[:instance_reader] == false
|
64
|
+
class_eval writer, __FILE__, line unless options[:instance_writer] == false
|
62
65
|
end
|
63
66
|
end
|
64
67
|
end
|
@@ -37,12 +37,12 @@ class Array
|
|
37
37
|
# Converts a collection of elements into a formatted string by calling
|
38
38
|
# <tt>to_s</tt> on all elements and joining them:
|
39
39
|
#
|
40
|
-
# Blog.
|
40
|
+
# Blog.all.to_formatted_s # => "First PostSecond PostThird Post"
|
41
41
|
#
|
42
42
|
# Adding in the <tt>:db</tt> argument as the format yields a prettier
|
43
43
|
# output:
|
44
44
|
#
|
45
|
-
# Blog.
|
45
|
+
# Blog.all.to_formatted_s(:db) # => "First Post,Second Post,Third Post"
|
46
46
|
def to_formatted_s(format = :default)
|
47
47
|
case format
|
48
48
|
when :db
|
@@ -7,7 +7,7 @@ class Array
|
|
7
7
|
#
|
8
8
|
# [1,2,3,4,5,6].sample # => 4
|
9
9
|
# [1,2,3,4,5,6].sample(3) # => [2, 4, 5]
|
10
|
-
# [1,2,3,4,5,6].sample(-3) # => ArgumentError: negative
|
10
|
+
# [1,2,3,4,5,6].sample(-3) # => ArgumentError: negative array size
|
11
11
|
# [].sample # => nil
|
12
12
|
# [].sample(3) # => []
|
13
13
|
def sample(n=nil)
|
@@ -1,8 +1,7 @@
|
|
1
1
|
class Array
|
2
|
-
#
|
2
|
+
# Returns an unique array based on the criteria given as a +Proc+.
|
3
3
|
#
|
4
|
-
# [1, 2, 3, 4].uniq_by { |i| i.odd? }
|
5
|
-
# # => [1, 2]
|
4
|
+
# [1, 2, 3, 4].uniq_by { |i| i.odd? } # => [1, 2]
|
6
5
|
#
|
7
6
|
def uniq_by
|
8
7
|
hash, array = {}, []
|
@@ -130,7 +130,6 @@ class Class # :nodoc:
|
|
130
130
|
end
|
131
131
|
|
132
132
|
def write_inheritable_attribute(key, value)
|
133
|
-
ActiveSupport::Deprecation.warn ClassInheritableAttributes::DEPRECATION_WARNING_MESSAGE
|
134
133
|
if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
|
135
134
|
@inheritable_attributes = {}
|
136
135
|
end
|
@@ -148,7 +147,6 @@ class Class # :nodoc:
|
|
148
147
|
end
|
149
148
|
|
150
149
|
def read_inheritable_attribute(key)
|
151
|
-
ActiveSupport::Deprecation.warn ClassInheritableAttributes::DEPRECATION_WARNING_MESSAGE
|
152
150
|
inheritable_attributes[key]
|
153
151
|
end
|
154
152
|
|
@@ -206,7 +206,7 @@ class Date
|
|
206
206
|
|
207
207
|
# Returns a new ; DateTime objects will have time set to 0:00DateTime representing the start of the month (1st of the month; DateTime objects will have time set to 0:00)
|
208
208
|
def beginning_of_month
|
209
|
-
self.acts_like?(:time) ? change(:day => 1
|
209
|
+
self.acts_like?(:time) ? change(:day => 1, :hour => 0) : change(:day => 1)
|
210
210
|
end
|
211
211
|
alias :at_beginning_of_month :beginning_of_month
|
212
212
|
|
@@ -231,13 +231,13 @@ class Date
|
|
231
231
|
|
232
232
|
# Returns a new Date/DateTime representing the start of the year (1st of january; DateTime objects will have time set to 0:00)
|
233
233
|
def beginning_of_year
|
234
|
-
self.acts_like?(:time) ? change(:month => 1, :day => 1, :hour => 0
|
234
|
+
self.acts_like?(:time) ? change(:month => 1, :day => 1, :hour => 0) : change(:month => 1, :day => 1)
|
235
235
|
end
|
236
236
|
alias :at_beginning_of_year :beginning_of_year
|
237
237
|
|
238
238
|
# Returns a new Time representing the end of the year (31st of december; DateTime objects will have time set to 23:59:59)
|
239
239
|
def end_of_year
|
240
|
-
self.acts_like?(:time) ? change(:month => 12
|
240
|
+
self.acts_like?(:time) ? change(:month => 12, :day => 31, :hour => 23, :min => 59, :sec => 59) : change(:month => 12, :day => 31)
|
241
241
|
end
|
242
242
|
alias :at_end_of_year :end_of_year
|
243
243
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'date'
|
2
2
|
require 'active_support/inflector/methods'
|
3
3
|
require 'active_support/core_ext/date/zones'
|
4
|
+
require 'active_support/core_ext/module/remove_method'
|
4
5
|
|
5
6
|
class Date
|
6
7
|
DATE_FORMATS = {
|
@@ -13,10 +14,10 @@ class Date
|
|
13
14
|
}
|
14
15
|
|
15
16
|
# Ruby 1.9 has Date#to_time which converts to localtime only.
|
16
|
-
|
17
|
+
remove_possible_method :to_time
|
17
18
|
|
18
19
|
# Ruby 1.9 has Date#xmlschema which converts to a string without the time component.
|
19
|
-
|
20
|
+
remove_possible_method :xmlschema
|
20
21
|
|
21
22
|
# Convert to a formatted string. See DATE_FORMATS for predefined formats.
|
22
23
|
#
|
@@ -51,25 +51,25 @@ class DateTime
|
|
51
51
|
utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
|
52
52
|
end
|
53
53
|
|
54
|
-
# Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005 14:30:00 +0000"
|
54
|
+
# Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005 14:30:00 +0000".
|
55
55
|
def readable_inspect
|
56
56
|
to_s(:rfc822)
|
57
57
|
end
|
58
58
|
alias_method :default_inspect, :inspect
|
59
59
|
alias_method :inspect, :readable_inspect
|
60
60
|
|
61
|
-
# Converts self to a Ruby Date object; time portion is discarded
|
61
|
+
# Converts self to a Ruby Date object; time portion is discarded.
|
62
62
|
def to_date
|
63
63
|
::Date.new(year, month, day)
|
64
64
|
end unless instance_methods(false).include?(:to_date)
|
65
65
|
|
66
|
-
# Attempts to convert self to a Ruby Time object; returns self if out of range of Ruby Time class
|
67
|
-
# If self has an offset other than 0, self will just be returned unaltered, since there's no clean way to map it to a Time
|
66
|
+
# Attempts to convert self to a Ruby Time object; returns self if out of range of Ruby Time class.
|
67
|
+
# If self has an offset other than 0, self will just be returned unaltered, since there's no clean way to map it to a Time.
|
68
68
|
def to_time
|
69
69
|
self.offset == 0 ? ::Time.utc_time(year, month, day, hour, min, sec, sec_fraction * (RUBY_VERSION < '1.9' ? 86400000000 : 1000000)) : self
|
70
70
|
end
|
71
71
|
|
72
|
-
# To be able to keep Times, Dates and DateTimes interchangeable on conversions
|
72
|
+
# To be able to keep Times, Dates and DateTimes interchangeable on conversions.
|
73
73
|
def to_datetime
|
74
74
|
self
|
75
75
|
end unless instance_methods(false).include?(:to_datetime)
|
@@ -79,17 +79,17 @@ class DateTime
|
|
79
79
|
civil(year, month, day, hour, min, sec, offset)
|
80
80
|
end
|
81
81
|
|
82
|
-
# Converts datetime to an appropriate format for use in XML
|
82
|
+
# Converts datetime to an appropriate format for use in XML.
|
83
83
|
def xmlschema
|
84
84
|
strftime("%Y-%m-%dT%H:%M:%S%Z")
|
85
85
|
end unless instance_methods(false).include?(:xmlschema)
|
86
86
|
|
87
|
-
# Converts self to a floating-point number of seconds since the Unix epoch
|
87
|
+
# Converts self to a floating-point number of seconds since the Unix epoch.
|
88
88
|
def to_f
|
89
89
|
seconds_since_unix_epoch.to_f
|
90
90
|
end
|
91
91
|
|
92
|
-
# Converts self to an integer number of seconds since the Unix epoch
|
92
|
+
# Converts self to an integer number of seconds since the Unix epoch.
|
93
93
|
def to_i
|
94
94
|
seconds_since_unix_epoch.to_i
|
95
95
|
end
|
@@ -108,7 +108,8 @@ class Hash
|
|
108
108
|
raise "can't typecast #{entries.inspect}"
|
109
109
|
end
|
110
110
|
end
|
111
|
-
elsif value['type'] == 'file' ||
|
111
|
+
elsif value['type'] == 'file' ||
|
112
|
+
(value["__content__"] && (value.keys.size == 1 || value["__content__"].present?))
|
112
113
|
content = value["__content__"]
|
113
114
|
if parser = ActiveSupport::XmlMini::PARSING[value["type"]]
|
114
115
|
parser.arity == 1 ? parser.call(content) : parser.call(content, value)
|
@@ -9,4 +9,16 @@ class Hash
|
|
9
9
|
def with_indifferent_access
|
10
10
|
ActiveSupport::HashWithIndifferentAccess.new_from_hash_copying_default(self)
|
11
11
|
end
|
12
|
+
|
13
|
+
# Called when object is nested under an object that receives
|
14
|
+
# #with_indifferent_access. This method with be called on the current object
|
15
|
+
# by the enclosing object and is aliased to #with_indifferent_access by
|
16
|
+
# default. Subclasses of Hash may overwrite this method to return +self+ if
|
17
|
+
# converting to an +ActiveSupport::HashWithIndifferentAccess+ would not be
|
18
|
+
# desirable.
|
19
|
+
#
|
20
|
+
# b = {:b => 1}
|
21
|
+
# {:a => b}.with_indifferent_access["a"] # calls b.nested_under_indifferent_access
|
22
|
+
#
|
23
|
+
alias nested_under_indifferent_access with_indifferent_access
|
12
24
|
end
|
@@ -21,7 +21,7 @@ class Hash
|
|
21
21
|
|
22
22
|
# Replaces the hash with only the given keys.
|
23
23
|
# Returns a hash contained the removed key/value pairs
|
24
|
-
# {:a => 1, :b => 2, :c => 3, :d => 4}.slice!(:a, :b) # => {:c => 3, :d =>4}
|
24
|
+
# {:a => 1, :b => 2, :c => 3, :d => 4}.slice!(:a, :b) # => {:c => 3, :d => 4}
|
25
25
|
def slice!(*keys)
|
26
26
|
keys = keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
|
27
27
|
omit = slice(*self.keys - keys)
|
@@ -4,10 +4,13 @@ class Integer
|
|
4
4
|
# Ordinalize turns a number into an ordinal string used to denote the
|
5
5
|
# position in an ordered sequence such as 1st, 2nd, 3rd, 4th.
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
7
|
+
# 1.ordinalize # => "1st"
|
8
|
+
# 2.ordinalize # => "2nd"
|
9
|
+
# 1002.ordinalize # => "1002nd"
|
10
|
+
# 1003.ordinalize # => "1003rd"
|
11
|
+
# -11.ordinalize # => "-11th"
|
12
|
+
# -1001.ordinalize # => "-1001st"
|
13
|
+
#
|
11
14
|
def ordinalize
|
12
15
|
ActiveSupport::Inflector.ordinalize(self)
|
13
16
|
end
|
@@ -62,7 +62,7 @@ module Kernel
|
|
62
62
|
|
63
63
|
# Captures the given stream and returns it:
|
64
64
|
#
|
65
|
-
# stream = capture(:stdout){ puts "Cool" }
|
65
|
+
# stream = capture(:stdout) { puts "Cool" }
|
66
66
|
# stream # => "Cool\n"
|
67
67
|
#
|
68
68
|
def capture(stream)
|
@@ -78,4 +78,16 @@ module Kernel
|
|
78
78
|
result
|
79
79
|
end
|
80
80
|
alias :silence :capture
|
81
|
+
|
82
|
+
# Silences both STDOUT and STDERR, even for subprocesses.
|
83
|
+
#
|
84
|
+
# quietly { system 'bundle install' }
|
85
|
+
#
|
86
|
+
def quietly
|
87
|
+
silence_stream(STDOUT) do
|
88
|
+
silence_stream(STDERR) do
|
89
|
+
yield
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
81
93
|
end
|
@@ -19,6 +19,7 @@ class Module
|
|
19
19
|
# attr_accessor_with_default(:element_name) { name.underscore }
|
20
20
|
#
|
21
21
|
def attr_accessor_with_default(sym, default = Proc.new)
|
22
|
+
ActiveSupport::Deprecation.warn "attr_accessor_with_default is deprecated. Use Ruby instead!"
|
22
23
|
define_method(sym, block_given? ? default : Proc.new { default })
|
23
24
|
module_eval(<<-EVAL, __FILE__, __LINE__ + 1)
|
24
25
|
def #{sym}=(value) # def age=(value)
|
@@ -1,14 +1,14 @@
|
|
1
1
|
class Object
|
2
2
|
# An object is blank if it's false, empty, or a whitespace string.
|
3
|
-
# For example, "", " ", +nil+, [], and {} are blank.
|
3
|
+
# For example, "", " ", +nil+, [], and {} are all blank.
|
4
4
|
#
|
5
5
|
# This simplifies:
|
6
6
|
#
|
7
|
-
# if
|
7
|
+
# if address.nil? || address.empty?
|
8
8
|
#
|
9
9
|
# ...to:
|
10
10
|
#
|
11
|
-
# if
|
11
|
+
# if address.blank?
|
12
12
|
def blank?
|
13
13
|
respond_to?(:empty?) ? empty? : !self
|
14
14
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
#--
|
1
2
|
# Most objects are cloneable, but not all. For example you can't dup +nil+:
|
2
3
|
#
|
3
4
|
# nil.dup # => TypeError: can't dup NilClass
|
@@ -14,6 +15,7 @@
|
|
14
15
|
#
|
15
16
|
# That's why we hardcode the following cases and check duplicable? instead of
|
16
17
|
# using that rescue idiom.
|
18
|
+
#++
|
17
19
|
class Object
|
18
20
|
# Can you safely dup this object?
|
19
21
|
#
|
@@ -7,7 +7,7 @@ class Object
|
|
7
7
|
# provided. Each method called on the block variable must take an options
|
8
8
|
# hash as its final argument.
|
9
9
|
#
|
10
|
-
# Without with_options
|
10
|
+
# Without <tt>with_options></tt>, this code contains duplication:
|
11
11
|
#
|
12
12
|
# class Account < ActiveRecord::Base
|
13
13
|
# has_many :customers, :dependent => :destroy
|
@@ -16,7 +16,7 @@ class Object
|
|
16
16
|
# has_many :expenses, :dependent => :destroy
|
17
17
|
# end
|
18
18
|
#
|
19
|
-
# Using with_options
|
19
|
+
# Using <tt>with_options</tt>, we can remove the duplication:
|
20
20
|
#
|
21
21
|
# class Account < ActiveRecord::Base
|
22
22
|
# with_options :dependent => :destroy do |assoc|
|
@@ -29,11 +29,14 @@ class Object
|
|
29
29
|
#
|
30
30
|
# It can also be used with an explicit receiver:
|
31
31
|
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
32
|
+
# I18n.with_options :locale => user.locale, :scope => "newsletter" do |i18n|
|
33
|
+
# subject i18n.t :subject
|
34
|
+
# body i18n.t :body, :user_name => user.name
|
35
35
|
# end
|
36
36
|
#
|
37
|
+
# <tt>with_options</tt> can also be nested since the call is forwarded to its receiver.
|
38
|
+
# Each nesting level will merge inherited defaults in addition to their own.
|
39
|
+
#
|
37
40
|
def with_options(options)
|
38
41
|
yield ActiveSupport::OptionMerger.new(self, options)
|
39
42
|
end
|