active_support_core_extensions.md 114.8 KB
Newer Older
1 2
Active Support Core Extensions
==============================
3

X
Xavier Noria 已提交
4
Active Support is the Ruby on Rails component responsible for providing Ruby language extensions, utilities, and other transversal stuff.
5

X
Xavier Noria 已提交
6 7
It offers a richer bottom-line at the language level, targeted both at the development of Rails applications, and at the development of Ruby on Rails itself.

8
After reading this guide, you will know:
9

10
--------------------------------------------------------------------------------
11

12 13
How to Load Core Extensions
---------------------------
14

15
### Stand-Alone Active Support
16

17
In order to have a near-zero default footprint, Active Support does not load anything by default. It is broken in small pieces so that you can load just what you need, and also has some convenience entry points to load related extensions in one shot, even everything.
18 19 20

Thus, after a simple require like:

21
```ruby
22
require 'active_support'
23
```
24

25
objects do not even respond to `blank?`. Let's see how to load its definition.
26

27
#### Cherry-picking a Definition
28

29
The most lightweight way to get `blank?` is to cherry-pick the file that defines it.
30

31
For every single method defined as a core extension this guide has a note that says where such a method is defined. In the case of `blank?` the note reads:
32

33
NOTE: Defined in `active_support/core_ext/object/blank.rb`.
34 35 36

That means that this single call is enough:

37
```ruby
38
require 'active_support/core_ext/object/blank'
39
```
40 41 42

Active Support has been carefully revised so that cherry-picking a file loads only strictly needed dependencies, if any.

43
#### Loading Grouped Core Extensions
44

45
The next level is to simply load all extensions to `Object`. As a rule of thumb, extensions to `SomeClass` are available in one shot by loading `active_support/core_ext/some_class`.
46

47
Thus, to load all extensions to `Object` (including `blank?`):
48

49
```ruby
50
require 'active_support/core_ext/object'
51
```
52

53
#### Loading All Core Extensions
54 55 56

You may prefer just to load all core extensions, there is a file for that:

57
```ruby
58
require 'active_support/core_ext'
59
```
60

61
#### Loading All Active Support
62 63 64

And finally, if you want to have all Active Support available just issue:

65
```ruby
66
require 'active_support/all'
67
```
68

69
That does not even put the entire Active Support in memory upfront indeed, some stuff is configured via `autoload`, so it is only loaded if used.
70

71
### Active Support Within a Ruby on Rails Application
72

73
A Ruby on Rails application loads all Active Support unless `config.active_support.bare` is true. In that case, the application will only load what the framework itself cherry-picks for its own needs, and can still cherry-pick itself at any granularity level, as explained in the previous section.
74

75 76
Extensions to All Objects
-------------------------
77

78
### `blank?` and `present?`
79 80 81

The following values are considered to be blank in a Rails application:

82
* `nil` and `false`,
83

84
* strings composed only of whitespace (see note below),
85 86 87

* empty arrays and hashes, and

88
* any other object that responds to `empty?` and is empty.
89

90
INFO: The predicate for strings uses the Unicode-aware character class `[:space:]`, so for example U+2029 (paragraph separator) is considered to be whitespace.
91

A
Agis Anastasopoulos 已提交
92
WARNING: Note that numbers are not mentioned. In particular, 0 and 0.0 are **not** blank.
93

94
For example, this method from `ActionDispatch::Session::AbstractStore` uses `blank?` for checking whether a session key is present:
95

96
```ruby
X
Xavier Noria 已提交
97 98 99 100
def ensure_session_key!
  if @key.blank?
    raise ArgumentError, 'A key is required...'
  end
101
end
102
```
103

104
The method `present?` is equivalent to `!blank?`. This example is taken from `ActionDispatch::Http::Cache::Response`:
105

106
```ruby
X
Xavier Noria 已提交
107 108 109
def set_conditional_cache_control!
  return if self["Cache-Control"].present?
  ...
110
end
111
```
112

113
NOTE: Defined in `active_support/core_ext/object/blank.rb`.
114

115
### `presence`
X
Xavier Noria 已提交
116

117
The `presence` method returns its receiver if `present?`, and `nil` otherwise. It is useful for idioms like this:
X
Xavier Noria 已提交
118

119
```ruby
X
Xavier Noria 已提交
120
host = config[:host].presence || 'localhost'
121
```
X
Xavier Noria 已提交
122

123
NOTE: Defined in `active_support/core_ext/object/blank.rb`.
124

125
### `duplicable?`
126

127
A few fundamental objects in Ruby are singletons. For example, in the whole life of a program the integer 1 refers always to the same instance:
128

129
```ruby
130 131
1.object_id                 # => 3
Math.cos(0).to_i.object_id  # => 3
132
```
133

134
Hence, there's no way these objects can be duplicated through `dup` or `clone`:
135

136
```ruby
137
true.dup  # => TypeError: can't dup TrueClass
138
```
139 140 141

Some numbers which are not singletons are not duplicable either:

142
```ruby
143 144
0.0.clone        # => allocator undefined for Float
(2**1024).clone  # => allocator undefined for Bignum
145
```
146

147
Active Support provides `duplicable?` to programmatically query an object about this property:
148

149
```ruby
A
Agis Anastasopoulos 已提交
150
"foo".duplicable? # => true
V
Vijay Dev 已提交
151
"".duplicable?     # => true
A
Agis Anastasopoulos 已提交
152
0.0.duplicable?   # => false
V
Vijay Dev 已提交
153
false.duplicable?  # => false
154
```
155

156
By definition all objects are `duplicable?` except `nil`, `false`, `true`, symbols, numbers, class, and module objects.
157

158
WARNING: Any class can disallow duplication by removing `dup` and `clone` or raising exceptions from them. Thus only `rescue` can tell whether a given arbitrary object is duplicable. `duplicable?` depends on the hard-coded list above, but it is much faster than `rescue`. Use it only if you know the hard-coded list is enough in your use case.
159

160
NOTE: Defined in `active_support/core_ext/object/duplicable.rb`.
161

162
### `deep_dup`
A
Alexey Gaziev 已提交
163

164
The `deep_dup` method returns deep copy of a given object. Normally, when you `dup` an object that contains other objects, ruby does not `dup` them, so it creates a shallow copy of the object. If you have an array with a string, for example, it will look like this:
A
Alexey Gaziev 已提交
165

166
```ruby
167 168 169 170 171
array     = ['string']
duplicate = array.dup

duplicate.push 'another-string'

A
Agis Anastasopoulos 已提交
172
# the object was duplicated, so the element was added only to the duplicate
173 174 175 176 177
array     #=> ['string']
duplicate #=> ['string', 'another-string']

duplicate.first.gsub!('string', 'foo')

A
Agis Anastasopoulos 已提交
178
# first element was not duplicated, it will be changed in both arrays
179 180
array     #=> ['foo']
duplicate #=> ['foo', 'another-string']
181
```
A
Alexey Gaziev 已提交
182

A
Agis Anastasopoulos 已提交
183
As you can see, after duplicating the `Array` instance, we got another object, therefore we can modify it and the original object will stay unchanged. This is not true for array's elements, however. Since `dup` does not make deep copy, the string inside the array is still the same object.
A
Alexey Gaziev 已提交
184

185
If you need a deep copy of an object, you should use `deep_dup`. Here is an example:
A
Alexey Gaziev 已提交
186

187
```ruby
188
array     = ['string']
189
duplicate = array.deep_dup
190 191 192 193 194

duplicate.first.gsub!('string', 'foo')

array     #=> ['string']
duplicate #=> ['foo']
195
```
A
Alexey Gaziev 已提交
196

A
Agis Anastasopoulos 已提交
197
If the object is not duplicable, `deep_dup` will just return it:
A
Alexey Gaziev 已提交
198

199
```ruby
A
Alexey Gaziev 已提交
200
number = 1
A
Agis Anastasopoulos 已提交
201 202
duplicate = number.deep_dup
number.object_id == duplicate.object_id   # => true
203
```
A
Alexey Gaziev 已提交
204

205
NOTE: Defined in `active_support/core_ext/object/deep_dup.rb`.
A
Alexey Gaziev 已提交
206

207
### `try`
208

209
When you want to call a method on an object only if it is not `nil`, the simplest way to achieve it is with conditional statements, adding unnecessary clutter. The alternative is to use `try`. `try` is like `Object#send` except that it returns `nil` if sent to `nil`.
210 211

Here is an example:
V
Vijay Dev 已提交
212

213
```ruby
214 215 216 217 218 219 220
# without try
unless @number.nil?
  @number.next
end

# with try
@number.try(:next)
221
```
222

223
Another example is this code from `ActiveRecord::ConnectionAdapters::AbstractAdapter` where `@logger` could be `nil`. You can see that the code uses `try` and avoids an unnecessary check.
224

225
```ruby
226 227 228 229 230 231
def log_info(sql, name, ms)
  if @logger.try(:debug?)
    name = '%s (%.1fms)' % [name || 'SQL', ms]
    @logger.debug(format_log_entry(name, sql.squeeze(' ')))
  end
end
232
```
233

234
`try` can also be called without arguments but a block, which will only be executed if the object is not nil:
J
José Valim 已提交
235

236
```ruby
J
José Valim 已提交
237
@person.try { |p| "#{p.first_name} #{p.last_name}" }
238
```
J
José Valim 已提交
239

240
NOTE: Defined in `active_support/core_ext/object/try.rb`.
241

242
### `class_eval(*args, &block)`
243

244
You can evaluate code in the context of any object's singleton class using `class_eval`:
245

246
```ruby
247 248
class Proc
  def bind(object)
249
    block, time = self, Time.current
250 251 252 253 254 255 256 257 258
    object.class_eval do
      method_name = "__bind_#{time.to_i}_#{time.usec}"
      define_method(method_name, &block)
      method = instance_method(method_name)
      remove_method(method_name)
      method
    end.bind(object)
  end
end
259
```
260

261
NOTE: Defined in `active_support/core_ext/kernel/singleton_class.rb`.
262

263
### `acts_like?(duck)`
264

265
The method `acts_like?` provides a way to check whether some class acts like some other class based on a simple convention: a class that provides the same interface as `String` defines
266

267
```ruby
268 269
def acts_like_string?
end
270
```
271 272 273

which is only a marker, its body or return value are irrelevant. Then, client code can query for duck-type-safeness this way:

274
```ruby
275
some_klass.acts_like?(:string)
276
```
277

278
Rails has classes that act like `Date` or `Time` and follow this contract.
279

280
NOTE: Defined in `active_support/core_ext/object/acts_like.rb`.
281

282
### `to_param`
283

284
All objects in Rails respond to the method `to_param`, which is meant to return something that represents them as values in a query string, or as URL fragments.
285

286
By default `to_param` just calls `to_s`:
287

288
```ruby
289
7.to_param # => "7"
290
```
291

292
The return value of `to_param` should **not** be escaped:
293

294
```ruby
295
"Tom & Jerry".to_param # => "Tom & Jerry"
296
```
297 298 299

Several classes in Rails overwrite this method.

300
For example `nil`, `true`, and `false` return themselves. `Array#to_param` calls `to_param` on the elements and joins the result with "/":
301

302
```ruby
303
[0, true, String].to_param # => "0/true/String"
304
```
305

306
Notably, the Rails routing system calls `to_param` on models to get a value for the `:id` placeholder. `ActiveRecord::Base#to_param` returns the `id` of a model, but you can redefine that method in your models. For example, given
307

308
```ruby
309 310 311 312 313
class User
  def to_param
    "#{id}-#{name.parameterize}"
  end
end
314
```
315 316 317

we get:

318
```ruby
319
user_path(@user) # => "/users/357-john-smith"
320
```
321

322
WARNING. Controllers need to be aware of any redefinition of `to_param` because when a request like that comes in "357-john-smith" is the value of `params[:id]`.
323

324
NOTE: Defined in `active_support/core_ext/object/to_param.rb`.
325

326
### `to_query`
327

328
Except for hashes, given an unescaped `key` this method constructs the part of a query string that would map such key to what `to_param` returns. For example, given
329

330
```ruby
331 332 333 334 335
class User
  def to_param
    "#{id}-#{name.parameterize}"
  end
end
336
```
337 338 339

we get:

340
```ruby
341
current_user.to_query('user') # => user=357-john-smith
342
```
343 344 345

This method escapes whatever is needed, both for the key and the value:

346
```ruby
347
account.to_query('company[name]')
348
# => "company%5Bname%5D=Johnson+%26+Johnson"
349
```
350 351 352

so its output is ready to be used in a query string.

353
Arrays return the result of applying `to_query` to each element with `_key_[]` as key, and join the result with "&":
354

355
```ruby
356 357
[3.4, -45.6].to_query('sample')
# => "sample%5B%5D=3.4&sample%5B%5D=-45.6"
358
```
359

360
Hashes also respond to `to_query` but with a different signature. If no argument is passed a call generates a sorted series of key/value assignments calling `to_query(key)` on its values. Then it joins the result with "&":
361

362
```ruby
363
{c: 3, b: 2, a: 1}.to_query # => "a=1&b=2&c=3"
364
```
365

366
The method `Hash#to_query` accepts an optional namespace for the keys:
367

368
```ruby
369
{id: 89, name: "John Smith"}.to_query('user')
370
# => "user%5Bid%5D=89&user%5Bname%5D=John+Smith"
371
```
372

373
NOTE: Defined in `active_support/core_ext/object/to_query.rb`.
374

375
### `with_options`
376

377
The method `with_options` provides a way to factor out common options in a series of method calls.
378

379
Given a default options hash, `with_options` yields a proxy object to a block. Within the block, methods called on the proxy are forwarded to the receiver with their options merged. For example, you get rid of the duplication in:
380

381
```ruby
382
class Account < ActiveRecord::Base
383 384 385 386
  has_many :customers, dependent: :destroy
  has_many :products,  dependent: :destroy
  has_many :invoices,  dependent: :destroy
  has_many :expenses,  dependent: :destroy
387
end
388
```
389 390 391

this way:

392
```ruby
393
class Account < ActiveRecord::Base
394
  with_options dependent: :destroy do |assoc|
395 396 397 398 399 400
    assoc.has_many :customers
    assoc.has_many :products
    assoc.has_many :invoices
    assoc.has_many :expenses
  end
end
401
```
402 403 404

That idiom may convey _grouping_ to the reader as well. For example, say you want to send a newsletter whose language depends on the user. Somewhere in the mailer you could group locale-dependent bits like this:

405
```ruby
406
I18n.with_options locale: user.locale, scope: "newsletter" do |i18n|
407
  subject i18n.t :subject
408
  body    i18n.t :body, user_name: user.name
409
end
410
```
411

412
TIP: Since `with_options` forwards calls to its receiver they can be nested. Each nesting level will merge inherited defaults in addition to their own.
413

414
NOTE: Defined in `active_support/core_ext/object/with_options.rb`.
415

416
### Instance Variables
417 418 419

Active Support provides several methods to ease access to instance variables.

420
#### `instance_variable_names`
421

422
Ruby 1.8 and 1.9 have a method called `instance_variables` that returns the names of the defined instance variables. But they behave differently, in 1.8 it returns strings whereas in 1.9 it returns symbols. Active Support defines `instance_variable_names` as a portable way to obtain them as strings:
423

424
```ruby
425 426 427 428 429 430 431
class C
  def initialize(x, y)
    @x, @y = x, y
  end
end

C.new(0, 1).instance_variable_names # => ["@y", "@x"]
432
```
433

X
Xavier Noria 已提交
434
WARNING: The order in which the names are returned is unspecified, and it indeed depends on the version of the interpreter.
435

436
NOTE: Defined in `active_support/core_ext/object/instance_variables.rb`.
437

438
#### `instance_values`
439

440
The method `instance_values` returns a hash that maps instance variable names without "@" to their
441
corresponding values. Keys are strings:
442

443
```ruby
444 445 446 447 448 449 450
class C
  def initialize(x, y)
    @x, @y = x, y
  end
end

C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
451
```
452

453
NOTE: Defined in `active_support/core_ext/object/instance_variables.rb`.
454

455
### Silencing Warnings, Streams, and Exceptions
456

457
The methods `silence_warnings` and `enable_warnings` change the value of `$VERBOSE` accordingly for the duration of their block, and reset it afterwards:
458

459
```ruby
460
silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }
461
```
462

463
You can silence any stream while a block runs with `silence_stream`:
464

465
```ruby
466 467 468
silence_stream(STDOUT) do
  # STDOUT is silent here
end
469
```
470

471
The `quietly` method addresses the common use case where you want to silence STDOUT and STDERR, even in subprocesses:
472

473
```ruby
474
quietly { system 'bundle install' }
475
```
476 477 478

For example, the railties test suite uses that one in a few places to prevent command messages from being echoed intermixed with the progress status.

479
Silencing exceptions is also possible with `suppress`. This method receives an arbitrary number of exception classes. If an exception is raised during the execution of the block and is `kind_of?` any of the arguments, `suppress` captures it and returns silently. Otherwise the exception is reraised:
480

481
```ruby
482 483 484 485
# If the user is locked the increment is lost, no big deal.
suppress(ActiveRecord::StaleObjectError) do
  current_user.increment! :visits
end
486
```
487

488
NOTE: Defined in `active_support/core_ext/kernel/reporting.rb`.
489

490
### `in?`
491

492
The predicate `in?` tests if an object is included in another object or a list of objects. An `ArgumentError` exception will be raised if a single argument is passed and it does not respond to `include?`.
493

494
Examples of `in?`:
495

496
```ruby
497
1.in?(1,2)          # => true
V
Vijay Dev 已提交
498 499 500
1.in?([1,2])        # => true
"lo".in?("hello")   # => true
25.in?(30..50)      # => false
501
1.in?(1)            # => ArgumentError
502
```
503

504
NOTE: Defined in `active_support/core_ext/object/inclusion.rb`.
505

506
Extensions to `Module`
507
----------------------
508

509
### `alias_method_chain`
510 511 512

Using plain Ruby you can wrap methods with other methods, that's called _alias chaining_.

513
For example, let's say you'd like params to be strings in functional tests, as they are in real requests, but still want the convenience of assigning integers and other kind of values. To accomplish that you could wrap `ActionController::TestCase#process` this way in `test/test_helper.rb`:
514

515
```ruby
516 517 518 519 520 521 522 523 524 525
ActionController::TestCase.class_eval do
  # save a reference to the original process method
  alias_method :original_process, :process

  # now redefine process and delegate to original_process
  def process(action, params=nil, session=nil, flash=nil, http_method='GET')
    params = Hash[*params.map {|k, v| [k, v.to_s]}.flatten]
    original_process(action, params, session, flash, http_method)
  end
end
526
```
527

528
That's the method `get`, `post`, etc., delegate the work to.
529

530
That technique has a risk, it could be the case that `:original_process` was taken. To try to avoid collisions people choose some label that characterizes what the chaining is about:
531

532
```ruby
533 534 535 536 537 538 539 540
ActionController::TestCase.class_eval do
  def process_with_stringified_params(...)
    params = Hash[*params.map {|k, v| [k, v.to_s]}.flatten]
    process_without_stringified_params(action, params, session, flash, http_method)
  end
  alias_method :process_without_stringified_params, :process
  alias_method :process, :process_with_stringified_params
end
541
```
542

543
The method `alias_method_chain` provides a shortcut for that pattern:
544

545
```ruby
546 547 548 549 550 551 552
ActionController::TestCase.class_eval do
  def process_with_stringified_params(...)
    params = Hash[*params.map {|k, v| [k, v.to_s]}.flatten]
    process_without_stringified_params(action, params, session, flash, http_method)
  end
  alias_method_chain :process, :stringified_params
end
553
```
554

555
Rails uses `alias_method_chain` all over the code base. For example validations are added to `ActiveRecord::Base#save` by wrapping the method that way in a separate module specialized in validations.
556

557
NOTE: Defined in `active_support/core_ext/module/aliasing.rb`.
558

559
### Attributes
560

561
#### `alias_attribute`
562

V
Vijay Dev 已提交
563
Model attributes have a reader, a writer, and a predicate. You can alias a model attribute having the corresponding three methods defined for you in one shot. As in other aliasing methods, the new name is the first argument, and the old name is the second (my mnemonic is they go in the same order as if you did an assignment):
564

565
```ruby
566 567
class User < ActiveRecord::Base
  # let me refer to the email column as "login",
568
  # possibly meaningful for authentication code
569 570
  alias_attribute :login, :email
end
571
```
572

573
NOTE: Defined in `active_support/core_ext/module/aliasing.rb`.
574

575
#### Internal Attributes
576

R
comma  
rpq 已提交
577
When you are defining an attribute in a class that is meant to be subclassed, name collisions are a risk. That's remarkably important for libraries.
578

579
Active Support defines the macros `attr_internal_reader`, `attr_internal_writer`, and `attr_internal_accessor`. They behave like their Ruby built-in `attr_*` counterparts, except they name the underlying instance variable in a way that makes collisions less likely.
580

581
The macro `attr_internal` is a synonym for `attr_internal_accessor`:
582

583
```ruby
584 585 586 587 588 589 590 591 592
# library
class ThirdPartyLibrary::Crawler
  attr_internal :log_level
end

# client code
class MyCrawler < ThirdPartyLibrary::Crawler
  attr_accessor :log_level
end
593
```
594

595
In the previous example it could be the case that `:log_level` does not belong to the public interface of the library and it is only used for development. The client code, unaware of the potential conflict, subclasses and defines its own `:log_level`. Thanks to `attr_internal` there's no collision.
596

597
By default the internal instance variable is named with a leading underscore, `@_log_level` in the example above. That's configurable via `Module.attr_internal_naming_format` though, you can pass any `sprintf`-like format string with a leading `@` and a `%s` somewhere, which is where the name will be placed. The default is `"@_%s"`.
598 599 600

Rails uses internal attributes in a few spots, for examples for views:

601
```ruby
602 603 604 605 606 607 608
module ActionView
  class Base
    attr_internal :captures
    attr_internal :request, :layout
    attr_internal :controller, :template
  end
end
609
```
610

611
NOTE: Defined in `active_support/core_ext/module/attr_internal.rb`.
612

613
#### Module Attributes
614

615
The macros `mattr_reader`, `mattr_writer`, and `mattr_accessor` are analogous to the `cattr_*` macros defined for class. Check [Class Attributes](#class-attributes).
616 617 618

For example, the dependencies mechanism uses them:

619
```ruby
620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635
module ActiveSupport
  module Dependencies
    mattr_accessor :warnings_on_first_load
    mattr_accessor :history
    mattr_accessor :loaded
    mattr_accessor :mechanism
    mattr_accessor :load_paths
    mattr_accessor :load_once_paths
    mattr_accessor :autoloaded_constants
    mattr_accessor :explicitly_unloadable_constants
    mattr_accessor :logger
    mattr_accessor :log_activity
    mattr_accessor :constant_watch_stack
    mattr_accessor :constant_watch_stack_mutex
  end
end
636
```
637

638
NOTE: Defined in `active_support/core_ext/module/attribute_accessors.rb`.
639

640
### Parents
641

642
#### `parent`
643

644
The `parent` method on a nested named module returns the module that contains its corresponding constant:
645

646
```ruby
647 648 649 650 651 652 653 654 655 656
module X
  module Y
    module Z
    end
  end
end
M = X::Y::Z

X::Y::Z.parent # => X::Y
M.parent       # => X::Y
657
```
658

659
If the module is anonymous or belongs to the top-level, `parent` returns `Object`.
660

661
WARNING: Note that in that case `parent_name` returns `nil`.
662

663
NOTE: Defined in `active_support/core_ext/module/introspection.rb`.
664

665
#### `parent_name`
666

667
The `parent_name` method on a nested named module returns the fully-qualified name of the module that contains its corresponding constant:
668

669
```ruby
670 671 672 673 674 675 676 677 678 679
module X
  module Y
    module Z
    end
  end
end
M = X::Y::Z

X::Y::Z.parent_name # => "X::Y"
M.parent_name       # => "X::Y"
680
```
681

682
For top-level or anonymous modules `parent_name` returns `nil`.
683

684
WARNING: Note that in that case `parent` returns `Object`.
685

686
NOTE: Defined in `active_support/core_ext/module/introspection.rb`.
687

688
#### `parents`
689

690
The method `parents` calls `parent` on the receiver and upwards until `Object` is reached. The chain is returned in an array, from bottom to top:
691

692
```ruby
693 694 695 696 697 698 699 700 701 702
module X
  module Y
    module Z
    end
  end
end
M = X::Y::Z

X::Y::Z.parents # => [X::Y, X, Object]
M.parents       # => [X::Y, X, Object]
703
```
704

705
NOTE: Defined in `active_support/core_ext/module/introspection.rb`.
706

707
### Constants
708

709
The method `local_constants` returns the names of the constants that have been
710
defined in the receiver module:
711

712
```ruby
713 714 715 716 717 718 719 720 721
module X
  X1 = 1
  X2 = 2
  module Y
    Y1 = :y1
    X1 = :overrides_X1_above
  end
end

722 723
X.local_constants    # => [:X1, :X2, :Y]
X::Y.local_constants # => [:Y1, :X1]
724
```
725

726
The names are returned as symbols. (The deprecated method `local_constant_names` returns strings.)
727

728
NOTE: Defined in `active_support/core_ext/module/introspection.rb`.
729

730
#### Qualified Constant Names
731

732
The standard methods `const_defined?`, `const_get` , and `const_set` accept
733
bare constant names. Active Support extends this API to be able to pass
734
relative qualified constant names.
735

736 737
The new methods are `qualified_const_defined?`, `qualified_const_get`, and
`qualified_const_set`. Their arguments are assumed to be qualified constant
738 739
names relative to their receiver:

740
```ruby
741 742 743
Object.qualified_const_defined?("Math::PI")       # => true
Object.qualified_const_get("Math::PI")            # => 3.141592653589793
Object.qualified_const_set("Math::Phi", 1.618034) # => 1.618034
744
```
745 746 747

Arguments may be bare constant names:

748
```ruby
749
Math.qualified_const_get("E") # => 2.718281828459045
750
```
751 752

These methods are analogous to their builtin counterparts. In particular,
753
`qualified_constant_defined?` accepts an optional second argument to be
754
able to say whether you want the predicate to look in the ancestors.
755 756 757 758 759
This flag is taken into account for each constant in the expression while
walking down the path.

For example, given

760
```ruby
761 762 763 764 765 766 767 768 769
module M
  X = 1
end

module N
  class C
    include M
  end
end
770
```
771

772
`qualified_const_defined?` behaves this way:
773

774
```ruby
775 776 777
N.qualified_const_defined?("C::X", false) # => false
N.qualified_const_defined?("C::X", true)  # => true
N.qualified_const_defined?("C::X")        # => true
778
```
779

780
As the last example implies, the second argument defaults to true,
781
as in `const_defined?`.
782 783

For coherence with the builtin methods only relative paths are accepted.
784
Absolute qualified constant names like `::Math::PI` raise `NameError`.
785

786
NOTE: Defined in `active_support/core_ext/module/qualified_const.rb`.
787

788
### Reachable
789

790
A named module is reachable if it is stored in its corresponding constant. It means you can reach the module object via the constant.
791

792
That is what ordinarily happens, if a module is called "M", the `M` constant exists and holds it:
793

794
```ruby
795 796 797 798
module M
end

M.reachable? # => true
799
```
800 801 802

But since constants and modules are indeed kind of decoupled, module objects can become unreachable:

803
```ruby
804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821
module M
end

orphan = Object.send(:remove_const, :M)

# The module object is orphan now but it still has a name.
orphan.name # => "M"

# You cannot reach it via the constant M because it does not even exist.
orphan.reachable? # => false

# Let's define a module called "M" again.
module M
end

# The constant M exists now again, and it stores a module
# object called "M", but it is a new instance.
orphan.reachable? # => false
822
```
823

824
NOTE: Defined in `active_support/core_ext/module/reachable.rb`.
825

826
### Anonymous
827 828 829

A module may or may not have a name:

830
```ruby
831 832 833 834 835 836 837
module M
end
M.name # => "M"

N = Module.new
N.name # => "N"

838
Module.new.name # => nil
839
```
840

841
You can check whether a module has a name with the predicate `anonymous?`:
842

843
```ruby
844 845 846 847 848
module M
end
M.anonymous? # => false

Module.new.anonymous? # => true
849
```
850 851 852

Note that being unreachable does not imply being anonymous:

853
```ruby
854 855 856 857 858 859 860
module M
end

m = Object.send(:remove_const, :M)

m.reachable? # => false
m.anonymous? # => false
861
```
862 863 864

though an anonymous module is unreachable by definition.

865
NOTE: Defined in `active_support/core_ext/module/anonymous.rb`.
866

867
### Method Delegation
868

869
The macro `delegate` offers an easy way to forward methods.
870

871
Let's imagine that users in some application have login information in the `User` model but name and other data in a separate `Profile` model:
872

873
```ruby
874 875 876
class User < ActiveRecord::Base
  has_one :profile
end
877
```
878

879
With that configuration you get a user's name via his profile, `user.profile.name`, but it could be handy to still be able to access such attribute directly:
880

881
```ruby
882 883 884 885 886 887 888
class User < ActiveRecord::Base
  has_one :profile

  def name
    profile.name
  end
end
889
```
890

891
That is what `delegate` does for you:
892

893
```ruby
894 895 896
class User < ActiveRecord::Base
  has_one :profile

897
  delegate :name, to: :profile
898
end
899
```
900

901 902
It is shorter, and the intention more obvious.

903 904
The method must be public in the target.

905
The `delegate` macro accepts several methods:
906

907
```ruby
908
delegate :name, :age, :address, :twitter, to: :profile
909
```
910

911
When interpolated into a string, the `:to` option should become an expression that evaluates to the object the method is delegated to. Typically a string or symbol. Such an expression is evaluated in the context of the receiver:
912

913
```ruby
914
# delegates to the Rails constant
915
delegate :logger, to: :Rails
916 917

# delegates to the receiver's class
918
delegate :table_name, to: 'self.class'
919
```
920

921
WARNING: If the `:prefix` option is `true` this is less generic, see below.
922

923
By default, if the delegation raises `NoMethodError` and the target is `nil` the exception is propagated. You can ask that `nil` is returned instead with the `:allow_nil` option:
924

925
```ruby
926
delegate :name, to: :profile, allow_nil: true
927
```
928

929
With `:allow_nil` the call `user.name` returns `nil` if the user has no profile.
930

931
The option `:prefix` adds a prefix to the name of the generated method. This may be handy for example to get a better name:
932

933
```ruby
934
delegate :street, to: :address, prefix: true
935
```
936

937
The previous example generates `address_street` rather than `street`.
938

939
WARNING: Since in this case the name of the generated method is composed of the target object and target method names, the `:to` option must be a method name.
940 941 942

A custom prefix may also be configured:

943
```ruby
944
delegate :size, to: :attachment, prefix: :avatar
945
```
946

947
In the previous example the macro generates `avatar_size` rather than `size`.
948

949
NOTE: Defined in `active_support/core_ext/module/delegation.rb`
950

951
### Redefining Methods
952

953
There are cases where you need to define a method with `define_method`, but don't know whether a method with that name already exists. If it does, a warning is issued if they are enabled. No big deal, but not clean either.
954

955
The method `redefine_method` prevents such a potential warning, removing the existing method before if needed. Rails uses it in a few places, for instance when it generates an association's API:
956

957
```ruby
958 959 960 961 962 963 964 965 966 967
redefine_method("#{reflection.name}=") do |new_value|
  association = association_instance_get(reflection.name)

  if association.nil? || association.target != new_value
    association = association_proxy_class.new(self, reflection)
  end

  association.replace(new_value)
  association_instance_set(reflection.name, new_value.nil? ? nil : association)
end
968
```
969

970
NOTE: Defined in `active_support/core_ext/module/remove_method.rb`
971

972
Extensions to `Class`
973
---------------------
974

975
### Class Attributes
976

977
#### `class_attribute`
978

979
The method `class_attribute` declares one or more inheritable class attributes that can be overridden at any level down the hierarchy.
980

981
```ruby
982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000
class A
  class_attribute :x
end

class B < A; end

class C < B; end

A.x = :a
B.x # => :a
C.x # => :a

B.x = :b
A.x # => :a
C.x # => :b

C.x = :c
A.x # => :a
B.x # => :b
1001
```
1002

1003
For example `ActionMailer::Base` defines:
1004

1005
```ruby
1006 1007
class_attribute :default_params
self.default_params = {
1008 1009 1010 1011
  mime_version: "1.0",
  charset: "UTF-8",
  content_type: "text/plain",
  parts_order: [ "text/plain", "text/enriched", "text/html" ]
1012
}.freeze
1013
```
1014

1015
They can be also accessed and overridden at the instance level.
1016

1017
```ruby
1018 1019 1020 1021 1022 1023 1024 1025
A.x = 1

a1 = A.new
a2 = A.new
a2.x = 2

a1.x # => 1, comes from A
a2.x # => 2, overridden in a2
1026
```
1027

1028
The generation of the writer instance method can be prevented by setting the option `:instance_writer` to `false`.
1029

1030
```ruby
V
Vijay Dev 已提交
1031
module ActiveRecord
1032
  class Base
1033
    class_attribute :table_name_prefix, instance_writer: false
1034 1035 1036
    self.table_name_prefix = ""
  end
end
1037
```
1038

1039 1040
A model may find that option useful as a way to prevent mass-assignment from setting the attribute.

1041
The generation of the reader instance method can be prevented by setting the option `:instance_reader` to `false`.
1042

1043
```ruby
1044
class A
1045
  class_attribute :x, instance_reader: false
1046 1047
end

1048
A.new.x = 1 # NoMethodError
1049
```
1050

1051
For convenience `class_attribute` also defines an instance predicate which is the double negation of what the instance reader returns. In the examples above it would be called `x?`.
1052

1053
When `:instance_reader` is `false`, the instance predicate returns a `NoMethodError` just like the reader method.
1054

1055
NOTE: Defined in `active_support/core_ext/class/attribute.rb`
1056

1057
#### `cattr_reader`, `cattr_writer`, and `cattr_accessor`
1058

1059
The macros `cattr_reader`, `cattr_writer`, and `cattr_accessor` are analogous to their `attr_*` counterparts but for classes. They initialize a class variable to `nil` unless it already exists, and generate the corresponding class methods to access it:
1060

1061
```ruby
1062 1063 1064 1065 1066
class MysqlAdapter < AbstractAdapter
  # Generates class methods to access @@emulate_booleans.
  cattr_accessor :emulate_booleans
  self.emulate_booleans = true
end
1067
```
1068

1069
Instance methods are created as well for convenience, they are just proxies to the class attribute. So, instances can change the class attribute, but cannot override it as it happens with `class_attribute` (see above). For example given
1070

1071
```ruby
1072
module ActionView
1073
  class Base
1074 1075
    cattr_accessor :field_error_proc
    @@field_error_proc = Proc.new{ ... }
1076 1077
  end
end
1078
```
1079

1080
we can access `field_error_proc` in views.
1081

1082
The generation of the reader instance method can be prevented by setting `:instance_reader` to `false` and the generation of the writer instance method can be prevented by setting `:instance_writer` to `false`. Generation of both methods can be prevented by setting `:instance_accessor` to `false`. In all cases, the value must be exactly `false` and not any false value.
1083

1084
```ruby
1085 1086 1087
module A
  class B
    # No first_name instance reader is generated.
1088
    cattr_accessor :first_name, instance_reader: false
1089
    # No last_name= instance writer is generated.
1090
    cattr_accessor :last_name, instance_writer: false
1091
    # No surname instance reader or surname= writer is generated.
1092
    cattr_accessor :surname, instance_accessor: false
1093 1094
  end
end
1095
```
1096

1097
A model may find it useful to set `:instance_accessor` to `false` as a way to prevent mass-assignment from setting the attribute.
1098

1099
NOTE: Defined in `active_support/core_ext/class/attribute_accessors.rb`.
1100

1101
### Subclasses & Descendants
1102

1103
#### `subclasses`
1104

1105
The `subclasses` method returns the subclasses of the receiver:
1106

1107
```ruby
1108
class C; end
X
Xavier Noria 已提交
1109
C.subclasses # => []
1110

1111
class B < C; end
X
Xavier Noria 已提交
1112
C.subclasses # => [B]
1113

1114
class A < B; end
X
Xavier Noria 已提交
1115
C.subclasses # => [B]
1116

1117
class D < C; end
X
Xavier Noria 已提交
1118
C.subclasses # => [B, D]
1119
```
1120

X
Xavier Noria 已提交
1121
The order in which these classes are returned is unspecified.
1122

X
Xavier Noria 已提交
1123 1124
WARNING: This method is redefined in some Rails core classes but should be all compatible in Rails 3.1.

1125
NOTE: Defined in `active_support/core_ext/class/subclasses.rb`.
X
Xavier Noria 已提交
1126

1127
#### `descendants`
X
Xavier Noria 已提交
1128

1129
The `descendants` method returns all classes that are `<` than its receiver:
1130

1131
```ruby
1132
class C; end
X
Xavier Noria 已提交
1133
C.descendants # => []
1134 1135

class B < C; end
X
Xavier Noria 已提交
1136
C.descendants # => [B]
1137 1138

class A < B; end
X
Xavier Noria 已提交
1139
C.descendants # => [B, A]
1140 1141

class D < C; end
X
Xavier Noria 已提交
1142
C.descendants # => [B, A, D]
1143
```
1144

X
Xavier Noria 已提交
1145
The order in which these classes are returned is unspecified.
1146

1147
NOTE: Defined in `active_support/core_ext/class/subclasses.rb`.
1148

1149
Extensions to `String`
1150
----------------------
1151

1152
### Output Safety
1153

1154
#### Motivation
1155

1156
Inserting data into HTML templates needs extra care. For example, you can't just interpolate `@review.title` verbatim into an HTML page. For one thing, if the review title is "Flanagan & Matz rules!" the output won't be well-formed because an ampersand has to be escaped as "&amp;amp;". What's more, depending on the application, that may be a big security hole because users can inject malicious HTML setting a hand-crafted review title. Check out the section about cross-site scripting in the [Security guide](security.html#cross-site-scripting-xss) for further information about the risks.
1157

1158
#### Safe Strings
1159

1160 1161 1162 1163
Active Support has the concept of <i>(html) safe</i> strings since Rails 3. A safe string is one that is marked as being insertable into HTML as is. It is trusted, no matter whether it has been escaped or not.

Strings are considered to be <i>unsafe</i> by default:

1164
```ruby
1165
"".html_safe? # => false
1166
```
1167

1168
You can obtain a safe string from a given one with the `html_safe` method:
1169

1170
```ruby
1171 1172
s = "".html_safe
s.html_safe? # => true
1173
```
1174

1175
It is important to understand that `html_safe` performs no escaping whatsoever, it is just an assertion:
1176

1177
```ruby
1178 1179 1180
s = "<script>...</script>".html_safe
s.html_safe? # => true
s            # => "<script>...</script>"
1181
```
1182

1183
It is your responsibility to ensure calling `html_safe` on a particular string is fine.
1184

1185
If you append onto a safe string, either in-place with `concat`/`<<`, or with `+`, the result is a safe string. Unsafe arguments are escaped:
1186

1187
```ruby
1188
"".html_safe + "<" # => "&lt;"
1189
```
1190 1191 1192

Safe arguments are directly appended:

1193
```ruby
1194
"".html_safe + "<".html_safe # => "<"
1195
```
1196 1197 1198

These methods should not be used in ordinary views. In Rails 3 unsafe values are automatically escaped:

1199
```erb
1200
<%= @review.title %> <%# fine in Rails 3, escaped if needed %>
1201
```
1202

1203
To insert something verbatim use the `raw` helper rather than calling `html_safe`:
1204

1205
```erb
1206
<%= raw @cms.current_template %> <%# inserts @cms.current_template as is %>
1207
```
X
Xavier Noria 已提交
1208

1209
or, equivalently, use `<%==`:
X
Xavier Noria 已提交
1210

1211
```erb
X
Xavier Noria 已提交
1212
<%== @cms.current_template %> <%# inserts @cms.current_template as is %>
1213
```
1214

1215
The `raw` helper calls `html_safe` for you:
1216

1217
```ruby
1218 1219 1220
def raw(stringish)
  stringish.to_s.html_safe
end
1221
```
1222

1223
NOTE: Defined in `active_support/core_ext/string/output_safety.rb`.
1224

1225
#### Transformation
1226

1227
As a rule of thumb, except perhaps for concatenation as explained above, any method that may change a string gives you an unsafe string. These are `downcase`, `gsub`, `strip`, `chomp`, `underscore`, etc.
1228

1229
In the case of in-place transformations like `gsub!` the receiver itself becomes unsafe.
1230 1231 1232

INFO: The safety bit is lost always, no matter whether the transformation actually changed something.

1233
#### Conversion and Coercion
1234

1235
Calling `to_s` on a safe string returns a safe string, but coercion with `to_str` returns an unsafe string.
1236

1237
#### Copying
1238

1239
Calling `dup` or `clone` on safe strings yields safe strings.
1240

1241
### `squish`
1242

1243
The method `squish` strips leading and trailing whitespace, and substitutes runs of whitespace with a single space each:
1244

1245
```ruby
1246
" \n  foo\n\r \t bar \n".squish # => "foo bar"
1247
```
1248

1249
There's also the destructive version `String#squish!`.
1250

1251
NOTE: Defined in `active_support/core_ext/string/filters.rb`.
1252

1253
### `truncate`
1254

1255
The method `truncate` returns a copy of its receiver truncated after a given `length`:
1256

1257
```ruby
1258 1259
"Oh dear! Oh dear! I shall be late!".truncate(20)
# => "Oh dear! Oh dear!..."
1260
```
1261

1262
Ellipsis can be customized with the `:omission` option:
1263

1264
```ruby
1265
"Oh dear! Oh dear! I shall be late!".truncate(20, omission: '&hellip;')
1266
# => "Oh dear! Oh &hellip;"
1267
```
1268 1269 1270

Note in particular that truncation takes into account the length of the omission string.

1271
Pass a `:separator` to truncate the string at a natural break:
1272

1273
```ruby
1274
"Oh dear! Oh dear! I shall be late!".truncate(18)
1275
# => "Oh dear! Oh dea..."
1276
"Oh dear! Oh dear! I shall be late!".truncate(18, separator: ' ')
1277
# => "Oh dear! Oh..."
1278
```
1279

1280
The option `:separator` can be a regexp:
A
Alexey Gaziev 已提交
1281

1282
```ruby
1283
"Oh dear! Oh dear! I shall be late!".truncate(18, separator: /\s/)
A
Alexey Gaziev 已提交
1284
# => "Oh dear! Oh..."
1285
```
1286

1287
In above examples "dear" gets cut first, but then `:separator` prevents it.
1288

1289
NOTE: Defined in `active_support/core_ext/string/filters.rb`.
1290

1291
### `inquiry`
1292

1293
The `inquiry` method converts a string into a `StringInquirer` object making equality checks prettier.
1294

1295
```ruby
1296 1297
"production".inquiry.production? # => true
"active".inquiry.inactive?       # => false
1298
```
1299

1300
### `starts_with?` and `ends_with?`
1301

1302
Active Support defines 3rd person aliases of `String#start_with?` and `String#end_with?`:
1303

1304
```ruby
1305 1306
"foo".starts_with?("f") # => true
"foo".ends_with?("o")   # => true
1307
```
1308

1309
NOTE: Defined in `active_support/core_ext/string/starts_ends_with.rb`.
1310

1311
### `strip_heredoc`
X
Xavier Noria 已提交
1312

1313
The method `strip_heredoc` strips indentation in heredocs.
X
Xavier Noria 已提交
1314 1315 1316

For example in

1317
```ruby
X
Xavier Noria 已提交
1318 1319 1320 1321 1322 1323 1324 1325 1326
if options[:usage]
  puts <<-USAGE.strip_heredoc
    This command does such and such.

    Supported options are:
      -h         This message
      ...
  USAGE
end
1327
```
X
Xavier Noria 已提交
1328 1329 1330 1331 1332 1333

the user would see the usage message aligned against the left margin.

Technically, it looks for the least indented line in the whole string, and removes
that amount of leading whitespace.

1334
NOTE: Defined in `active_support/core_ext/string/strip.rb`.
X
Xavier Noria 已提交
1335

1336
### `indent`
1337 1338 1339

Indents the lines in the receiver:

1340
```ruby
1341 1342 1343 1344 1345 1346 1347 1348 1349
<<EOS.indent(2)
def some_method
  some_code
end
EOS
# =>
  def some_method
    some_code
  end
1350
```
1351

1352
The second argument, `indent_string`, specifies which indent string to use. The default is `nil`, which tells the method to make an educated guess peeking at the first indented line, and fallback to a space if there is none.
1353

1354
```ruby
1355 1356 1357
"  foo".indent(2)        # => "    foo"
"foo\n\t\tbar".indent(2) # => "\t\tfoo\n\t\t\t\tbar"
"foo".indent(2, "\t")    # => "\t\tfoo"
1358
```
1359

1360
While `indent_string` is tipically one space or tab, it may be any string.
1361

1362
The third argument, `indent_empty_lines`, is a flag that says whether empty lines should be indented. Default is false.
1363

1364
```ruby
1365 1366
"foo\n\nbar".indent(2)            # => "  foo\n\n  bar"
"foo\n\nbar".indent(2, nil, true) # => "  foo\n  \n  bar"
1367
```
1368

1369
The `indent!` method performs indentation in-place.
1370

1371
### Access
1372

1373
#### `at(position)`
1374

1375
Returns the character of the string at position `position`:
1376

1377
```ruby
1378 1379 1380
"hello".at(0)  # => "h"
"hello".at(4)  # => "o"
"hello".at(-1) # => "o"
1381
"hello".at(10) # => nil
1382
```
1383

1384
NOTE: Defined in `active_support/core_ext/string/access.rb`.
1385

1386
#### `from(position)`
1387

1388
Returns the substring of the string starting at position `position`:
1389

1390
```ruby
1391 1392 1393 1394
"hello".from(0)  # => "hello"
"hello".from(2)  # => "llo"
"hello".from(-2) # => "lo"
"hello".from(10) # => "" if < 1.9, nil in 1.9
1395
```
1396

1397
NOTE: Defined in `active_support/core_ext/string/access.rb`.
1398

1399
#### `to(position)`
1400

1401
Returns the substring of the string up to position `position`:
1402

1403
```ruby
1404 1405 1406 1407
"hello".to(0)  # => "h"
"hello".to(2)  # => "hel"
"hello".to(-2) # => "hell"
"hello".to(10) # => "hello"
1408
```
1409

1410
NOTE: Defined in `active_support/core_ext/string/access.rb`.
1411

1412
#### `first(limit = 1)`
1413

1414
The call `str.first(n)` is equivalent to `str.to(n-1)` if `n` > 0, and returns an empty string for `n` == 0.
1415

1416
NOTE: Defined in `active_support/core_ext/string/access.rb`.
1417

1418
#### `last(limit = 1)`
1419

1420
The call `str.last(n)` is equivalent to `str.from(-n)` if `n` > 0, and returns an empty string for `n` == 0.
1421

1422
NOTE: Defined in `active_support/core_ext/string/access.rb`.
1423

1424
### Inflections
1425

1426
#### `pluralize`
1427

1428
The method `pluralize` returns the plural of its receiver:
1429

1430
```ruby
1431 1432 1433
"table".pluralize     # => "tables"
"ruby".pluralize      # => "rubies"
"equipment".pluralize # => "equipment"
1434
```
1435

1436
As the previous example shows, Active Support knows some irregular plurals and uncountable nouns. Built-in rules can be extended in `config/initializers/inflections.rb`. That file is generated by the `rails` command and has instructions in comments.
1437

1438
`pluralize` can also take an optional `count` parameter.  If `count == 1` the singular form will be returned.  For any other value of `count` the plural form will be returned:
1439

1440
```ruby
1441 1442 1443
"dude".pluralize(0) # => "dudes"
"dude".pluralize(1) # => "dude"
"dude".pluralize(2) # => "dudes"
1444
```
1445

1446 1447
Active Record uses this method to compute the default table name that corresponds to a model:

1448
```ruby
1449 1450 1451 1452 1453 1454
# active_record/base.rb
def undecorated_table_name(class_name = base_class.name)
  table_name = class_name.to_s.demodulize.underscore
  table_name = table_name.pluralize if pluralize_table_names
  table_name
end
1455
```
1456

1457
NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
1458

1459
#### `singularize`
1460

1461
The inverse of `pluralize`:
1462

1463
```ruby
1464 1465 1466
"tables".singularize    # => "table"
"rubies".singularize    # => "ruby"
"equipment".singularize # => "equipment"
1467
```
1468 1469 1470

Associations compute the name of the corresponding default associated class using this method:

1471
```ruby
1472 1473 1474 1475 1476 1477
# active_record/reflection.rb
def derive_class_name
  class_name = name.to_s.camelize
  class_name = class_name.singularize if collection?
  class_name
end
1478
```
1479

1480
NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
1481

1482
#### `camelize`
1483

1484
The method `camelize` returns its receiver in camel case:
1485

1486
```ruby
1487 1488
"product".camelize    # => "Product"
"admin_user".camelize # => "AdminUser"
1489
```
1490 1491 1492

As a rule of thumb you can think of this method as the one that transforms paths into Ruby class or module names, where slashes separate namespaces:

1493
```ruby
1494
"backoffice/session".camelize # => "Backoffice::Session"
1495
```
1496 1497 1498

For example, Action Pack uses this method to load the class that provides a certain session store:

1499
```ruby
1500 1501
# action_controller/metal/session_management.rb
def session_store=(store)
1502 1503 1504
  @@session_store = store.is_a?(Symbol) ?
    ActionDispatch::Session.const_get(store.to_s.camelize) :
    store
1505
end
1506
```
1507

1508
`camelize` accepts an optional argument, it can be `:upper` (default), or `:lower`. With the latter the first letter becomes lowercase:
1509

1510
```ruby
1511
"visual_effect".camelize(:lower) # => "visualEffect"
1512
```
1513 1514 1515

That may be handy to compute method names in a language that follows that convention, for example JavaScript.

1516
INFO: As a rule of thumb you can think of `camelize` as the inverse of `underscore`, though there are cases where that does not hold: `"SSLError".underscore.camelize` gives back `"SslError"`. To support cases such as this, Active Support allows you to specify acronyms in `config/initializers/inflections.rb`:
1517

1518
```ruby
1519 1520 1521 1522 1523
ActiveSupport::Inflector.inflections do |inflect|
  inflect.acronym 'SSL'
end

"SSLError".underscore.camelize #=> "SSLError"
1524
```
1525

1526
`camelize` is aliased to `camelcase`.
1527

1528
NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
1529

1530
#### `underscore`
1531

1532
The method `underscore` goes the other way around, from camel case to paths:
1533

1534
```ruby
1535 1536
"Product".underscore   # => "product"
"AdminUser".underscore # => "admin_user"
1537
```
1538 1539 1540

Also converts "::" back to "/":

1541
```ruby
1542
"Backoffice::Session".underscore # => "backoffice/session"
1543
```
1544 1545 1546

and understands strings that start with lowercase:

1547
```ruby
1548
"visualEffect".underscore # => "visual_effect"
1549
```
1550

1551
`underscore` accepts no argument though.
1552

1553
Rails class and module autoloading uses `underscore` to infer the relative path without extension of a file that would define a given missing constant:
1554

1555
```ruby
1556 1557 1558 1559 1560 1561 1562
# active_support/dependencies.rb
def load_missing_constant(from_mod, const_name)
  ...
  qualified_name = qualified_name_for from_mod, const_name
  path_suffix = qualified_name.underscore
  ...
end
1563
```
1564

1565
INFO: As a rule of thumb you can think of `underscore` as the inverse of `camelize`, though there are cases where that does not hold. For example, `"SSLError".underscore.camelize` gives back `"SslError"`.
1566

1567
NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
1568

1569
#### `titleize`
1570

1571
The method `titleize` capitalizes the words in the receiver:
1572

1573
```ruby
1574 1575
"alice in wonderland".titleize # => "Alice In Wonderland"
"fermat's enigma".titleize     # => "Fermat's Enigma"
1576
```
1577

1578
`titleize` is aliased to `titlecase`.
1579

1580
NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
1581

1582
#### `dasherize`
1583

1584
The method `dasherize` replaces the underscores in the receiver with dashes:
1585

1586
```ruby
1587 1588
"name".dasherize         # => "name"
"contact_data".dasherize # => "contact-data"
1589
```
1590 1591 1592

The XML serializer of models uses this method to dasherize node names:

1593
```ruby
1594 1595 1596 1597 1598
# active_model/serializers/xml.rb
def reformat_name(name)
  name = name.camelize if camelize?
  dasherize? ? name.dasherize : name
end
1599
```
1600

1601
NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
1602

1603
#### `demodulize`
1604

1605
Given a string with a qualified constant name, `demodulize` returns the very constant name, that is, the rightmost part of it:
1606

1607
```ruby
1608 1609 1610
"Product".demodulize                        # => "Product"
"Backoffice::UsersController".demodulize    # => "UsersController"
"Admin::Hotel::ReservationUtils".demodulize # => "ReservationUtils"
1611
```
1612 1613 1614

Active Record for example uses this method to compute the name of a counter cache column:

1615
```ruby
1616 1617 1618 1619 1620 1621 1622 1623
# active_record/reflection.rb
def counter_cache_column
  if options[:counter_cache] == true
    "#{active_record.name.demodulize.underscore.pluralize}_count"
  elsif options[:counter_cache]
    options[:counter_cache]
  end
end
1624
```
1625

1626
NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
1627

1628
#### `deconstantize`
1629

1630
Given a string with a qualified constant reference expression, `deconstantize` removes the rightmost segment, generally leaving the name of the constant's container:
1631

1632
```ruby
1633 1634 1635
"Product".deconstantize                        # => ""
"Backoffice::UsersController".deconstantize    # => "Backoffice"
"Admin::Hotel::ReservationUtils".deconstantize # => "Admin::Hotel"
1636
```
1637

1638
Active Support for example uses this method in `Module#qualified_const_set`:
1639

1640
```ruby
1641 1642 1643 1644 1645 1646 1647 1648
def qualified_const_set(path, value)
  QualifiedConstUtils.raise_if_absolute(path)

  const_name = path.demodulize
  mod_name = path.deconstantize
  mod = mod_name.empty? ? self : qualified_const_get(mod_name)
  mod.const_set(const_name, value)
end
1649
```
1650

1651
NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
1652

1653
#### `parameterize`
1654

1655
The method `parameterize` normalizes its receiver in a way that can be used in pretty URLs.
1656

1657
```ruby
1658 1659
"John Smith".parameterize # => "john-smith"
"Kurt Gödel".parameterize # => "kurt-godel"
1660
```
1661

1662
In fact, the result string is wrapped in an instance of `ActiveSupport::Multibyte::Chars`.
1663

1664
NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
1665

1666
#### `tableize`
1667

1668
The method `tableize` is `underscore` followed by `pluralize`.
1669

1670
```ruby
1671 1672
"Person".tableize      # => "people"
"Invoice".tableize     # => "invoices"
1673
"InvoiceLine".tableize # => "invoice_lines"
1674
```
1675

1676
As a rule of thumb, `tableize` returns the table name that corresponds to a given model for simple cases. The actual implementation in Active Record is not straight `tableize` indeed, because it also demodulizes the class name and checks a few options that may affect the returned string.
1677

1678
NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
1679

1680
#### `classify`
1681

1682
The method `classify` is the inverse of `tableize`. It gives you the class name corresponding to a table name:
1683

1684
```ruby
1685 1686 1687
"people".classify        # => "Person"
"invoices".classify      # => "Invoice"
"invoice_lines".classify # => "InvoiceLine"
1688
```
1689 1690 1691

The method understands qualified table names:

1692
```ruby
1693
"highrise_production.companies".classify # => "Company"
1694
```
1695

1696
Note that `classify` returns a class name as a string. You can get the actual class object invoking `constantize` on it, explained next.
1697

1698
NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
1699

1700
#### `constantize`
1701

1702
The method `constantize` resolves the constant reference expression in its receiver:
1703

1704
```ruby
1705 1706 1707 1708 1709 1710
"Fixnum".constantize # => Fixnum

module M
  X = 1
end
"M::X".constantize # => 1
1711
```
1712

1713
If the string evaluates to no known constant, or its content is not even a valid constant name, `constantize` raises `NameError`.
1714

1715
Constant name resolution by `constantize` starts always at the top-level `Object` even if there is no leading "::".
1716

1717
```ruby
1718 1719 1720 1721 1722 1723 1724 1725
X = :in_Object
module M
  X = :in_M

  X                 # => :in_M
  "::X".constantize # => :in_Object
  "X".constantize   # => :in_Object (!)
end
1726
```
1727 1728 1729

So, it is in general not equivalent to what Ruby would do in the same spot, had a real constant be evaluated.

1730
Mailer test cases obtain the mailer being tested from the name of the test class using `constantize`:
1731

1732
```ruby
1733 1734 1735 1736 1737 1738
# action_mailer/test_case.rb
def determine_default_mailer(name)
  name.sub(/Test$/, '').constantize
rescue NameError => e
  raise NonInferrableMailerError.new(name)
end
1739
```
1740

1741
NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
1742

1743
#### `humanize`
1744

1745
The method `humanize` gives you a sensible name for display out of an attribute name. To do so it replaces underscores with spaces, removes any "_id" suffix, and capitalizes the first word:
1746

1747
```ruby
1748 1749 1750
"name".humanize           # => "Name"
"author_id".humanize      # => "Author"
"comments_count".humanize # => "Comments count"
1751
```
1752

1753
The helper method `full_messages` uses `humanize` as a fallback to include attribute names:
1754

1755
```ruby
1756 1757 1758 1759 1760 1761
def full_messages
  full_messages = []

  each do |attribute, messages|
    ...
    attr_name = attribute.to_s.gsub('.', '_').humanize
1762
    attr_name = @base.class.human_attribute_name(attribute, default: attr_name)
1763 1764 1765 1766 1767
    ...
  end

  full_messages
end
1768
```
1769

1770
NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
1771

1772
#### `foreign_key`
1773

1774
The method `foreign_key` gives a foreign key column name from a class name. To do so it demodulizes, underscores, and adds "_id":
1775

1776
```ruby
1777 1778 1779
"User".foreign_key           # => "user_id"
"InvoiceLine".foreign_key    # => "invoice_line_id"
"Admin::Session".foreign_key # => "session_id"
1780
```
1781 1782 1783

Pass a false argument if you do not want the underscore in "_id":

1784
```ruby
1785
"User".foreign_key(false) # => "userid"
1786
```
1787

1788
Associations use this method to infer foreign keys, for example `has_one` and `has_many` do this:
1789

1790
```ruby
1791 1792
# active_record/associations.rb
foreign_key = options[:foreign_key] || reflection.active_record.name.foreign_key
1793
```
1794

1795
NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
1796

1797
### Conversions
1798

1799
#### `to_date`, `to_time`, `to_datetime`
1800

1801
The methods `to_date`, `to_time`, and `to_datetime` are basically convenience wrappers around `Date._parse`:
1802

1803
```ruby
1804 1805
"2010-07-27".to_date              # => Tue, 27 Jul 2010
"2010-07-27 23:37:00".to_time     # => Tue Jul 27 23:37:00 UTC 2010
1806
"2010-07-27 23:37:00".to_datetime # => Tue, 27 Jul 2010 23:37:00 +0000
1807
```
1808

1809
`to_time` receives an optional argument `:utc` or `:local`, to indicate which time zone you want the time in:
1810

1811
```ruby
1812 1813
"2010-07-27 23:42:00".to_time(:utc)   # => Tue Jul 27 23:42:00 UTC 2010
"2010-07-27 23:42:00".to_time(:local) # => Tue Jul 27 23:42:00 +0200 2010
1814
```
1815

1816
Default is `:utc`.
1817

1818
Please refer to the documentation of `Date._parse` for further details.
1819

1820
INFO: The three of them return `nil` for blank receivers.
1821

1822
NOTE: Defined in `active_support/core_ext/string/conversions.rb`.
1823

1824
Extensions to `Numeric`
1825
-----------------------
1826

1827
### Bytes
1828 1829 1830

All numbers respond to these methods:

1831
```ruby
1832 1833 1834 1835 1836 1837 1838
bytes
kilobytes
megabytes
gigabytes
terabytes
petabytes
exabytes
1839
```
1840 1841 1842

They return the corresponding amount of bytes, using a conversion factor of 1024:

1843
```ruby
1844 1845 1846 1847
2.kilobytes   # => 2048
3.megabytes   # => 3145728
3.5.gigabytes # => 3758096384
-4.exabytes   # => -4611686018427387904
1848
```
1849 1850 1851

Singular forms are aliased so you are able to say:

1852
```ruby
X
Xavier Noria 已提交
1853
1.megabyte # => 1048576
1854
```
1855

1856
NOTE: Defined in `active_support/core_ext/numeric/bytes.rb`.
1857

1858
### Time
A
Alexey Gaziev 已提交
1859

1860
Enables the use of time calculations and declarations, like `45.minutes + 2.hours + 4.years`.
A
Alexey Gaziev 已提交
1861 1862 1863 1864

These methods use Time#advance for precise date calculations when using from_now, ago, etc.
as well as adding or subtracting their results from a Time object. For example:

1865
```ruby
1866
# equivalent to Time.current.advance(months: 1)
A
Alexey Gaziev 已提交
1867 1868
1.month.from_now

1869
# equivalent to Time.current.advance(years: 2)
A
Alexey Gaziev 已提交
1870 1871
2.years.from_now

1872
# equivalent to Time.current.advance(months: 4, years: 5)
A
Alexey Gaziev 已提交
1873
(4.months + 5.years).from_now
1874
```
A
Alexey Gaziev 已提交
1875 1876 1877 1878 1879

While these methods provide precise calculation when used as in the examples above, care
should be taken to note that this is not true if the result of `months', `years', etc is
converted before use:

1880
```ruby
A
Alexey Gaziev 已提交
1881 1882 1883 1884 1885
# equivalent to 30.days.to_i.from_now
1.month.to_i.from_now

# equivalent to 365.25.days.to_f.from_now
1.year.to_f.from_now
1886
```
A
Alexey Gaziev 已提交
1887

1888 1889
In such cases, Ruby's core [Date](http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html) and
[Time](http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html) should be used for precision
A
Alexey Gaziev 已提交
1890 1891
date and time arithmetic.

1892
NOTE: Defined in `active_support/core_ext/numeric/time.rb`.
A
Alexey Gaziev 已提交
1893

1894
### Formatting
1895 1896 1897 1898

Enables the formatting of numbers in a variety of ways.

Produce a string representation of a number as a telephone number:
1899

1900
```ruby
V
Vijay Dev 已提交
1901 1902 1903 1904
5551234.to_s(:phone)
# => 555-1234
1235551234.to_s(:phone)
# => 123-555-1234
1905
1235551234.to_s(:phone, area_code: true)
V
Vijay Dev 已提交
1906
# => (123) 555-1234
1907
1235551234.to_s(:phone, delimiter: " ")
V
Vijay Dev 已提交
1908
# => 123 555 1234
1909
1235551234.to_s(:phone, area_code: true, extension: 555)
V
Vijay Dev 已提交
1910
# => (123) 555-1234 x 555
1911
1235551234.to_s(:phone, country_code: 1)
V
Vijay Dev 已提交
1912
# => +1-123-555-1234
1913
```
1914 1915

Produce a string representation of a number as currency:
1916

1917
```ruby
1918 1919
1234567890.50.to_s(:currency)                 # => $1,234,567,890.50
1234567890.506.to_s(:currency)                # => $1,234,567,890.51
1920
1234567890.506.to_s(:currency, precision: 3)  # => $1,234,567,890.506
1921
```
1922 1923

Produce a string representation of a number as a percentage:
1924

1925
```ruby
V
Vijay Dev 已提交
1926 1927
100.to_s(:percentage)
# => 100.000%
1928
100.to_s(:percentage, precision: 0)
V
Vijay Dev 已提交
1929
# => 100%
1930
1000.to_s(:percentage, delimiter: '.', separator: ',')
V
Vijay Dev 已提交
1931
# => 1.000,000%
1932
302.24398923423.to_s(:percentage, precision: 5)
V
Vijay Dev 已提交
1933
# => 302.24399%
1934
```
1935 1936

Produce a string representation of a number in delimited form:
1937

1938
```ruby
1939 1940
12345678.to_s(:delimited)                     # => 12,345,678
12345678.05.to_s(:delimited)                  # => 12,345,678.05
1941 1942 1943
12345678.to_s(:delimited, delimiter: ".")     # => 12.345.678
12345678.to_s(:delimited, delimiter: ",")     # => 12,345,678
12345678.05.to_s(:delimited, separator: " ")  # => 12,345,678 05
1944
```
1945 1946

Produce a string representation of a number rounded to a precision:
1947

1948
```ruby
1949
111.2345.to_s(:rounded)                     # => 111.235
1950 1951 1952 1953
111.2345.to_s(:rounded, precision: 2)       # => 111.23
13.to_s(:rounded, precision: 5)             # => 13.00000
389.32314.to_s(:rounded, precision: 0)      # => 389
111.2345.to_s(:rounded, significant: true)  # => 111
1954
```
1955 1956

Produce a string representation of a number as a human-readable number of bytes:
1957

1958
```ruby
V
Vijay Dev 已提交
1959 1960 1961 1962 1963 1964
123.to_s(:human_size)            # => 123 Bytes
1234.to_s(:human_size)           # => 1.21 KB
12345.to_s(:human_size)          # => 12.1 KB
1234567.to_s(:human_size)        # => 1.18 MB
1234567890.to_s(:human_size)     # => 1.15 GB
1234567890123.to_s(:human_size)  # => 1.12 TB
1965
```
1966 1967

Produce a string representation of a number in human-readable words:
1968

1969
```ruby
V
Vijay Dev 已提交
1970 1971 1972 1973 1974 1975 1976
123.to_s(:human)               # => "123"
1234.to_s(:human)              # => "1.23 Thousand"
12345.to_s(:human)             # => "12.3 Thousand"
1234567.to_s(:human)           # => "1.23 Million"
1234567890.to_s(:human)        # => "1.23 Billion"
1234567890123.to_s(:human)     # => "1.23 Trillion"
1234567890123456.to_s(:human)  # => "1.23 Quadrillion"
1977
```
1978

1979
NOTE: Defined in `active_support/core_ext/numeric/formatting.rb`.
1980

1981
Extensions to `Integer`
1982
-----------------------
1983

1984
### `multiple_of?`
1985

1986
The method `multiple_of?` tests whether an integer is multiple of the argument:
1987

1988
```ruby
1989 1990
2.multiple_of?(1) # => true
1.multiple_of?(2) # => false
1991
```
1992

1993
NOTE: Defined in `active_support/core_ext/integer/multiple.rb`.
1994

1995
### `ordinal`
1996

1997
The method `ordinal` returns the ordinal suffix string corresponding to the receiver integer:
1998

1999
```ruby
2000 2001 2002 2003 2004 2005
1.ordinal    # => "st"
2.ordinal    # => "nd"
53.ordinal   # => "rd"
2009.ordinal # => "th"
-21.ordinal  # => "st"
-134.ordinal # => "th"
2006
```
2007

2008
NOTE: Defined in `active_support/core_ext/integer/inflections.rb`.
2009

2010
### `ordinalize`
2011

2012
The method `ordinalize` returns the ordinal string corresponding to the receiver integer. In comparison, note that the `ordinal` method returns **only** the suffix string.
2013

2014
```ruby
2015 2016 2017 2018
1.ordinalize    # => "1st"
2.ordinalize    # => "2nd"
53.ordinalize   # => "53rd"
2009.ordinalize # => "2009th"
2019 2020
-21.ordinalize  # => "-21st"
-134.ordinalize # => "-134th"
2021
```
2022

2023
NOTE: Defined in `active_support/core_ext/integer/inflections.rb`.
2024

2025
Extensions to `BigDecimal`
2026
--------------------------
2027 2028 2029

...

2030
Extensions to `Enumerable`
2031
--------------------------
2032

2033
### `sum`
2034

2035
The method `sum` adds the elements of an enumerable:
2036

2037
```ruby
2038 2039
[1, 2, 3].sum # => 6
(1..100).sum  # => 5050
2040
```
2041

2042
Addition only assumes the elements respond to `+`:
2043

2044
```ruby
2045 2046
[[1, 2], [2, 3], [3, 4]].sum    # => [1, 2, 2, 3, 3, 4]
%w(foo bar baz).sum             # => "foobarbaz"
2047
{a: 1, b: 2, c: 3}.sum # => [:b, 2, :c, 3, :a, 1]
2048
```
2049 2050 2051

The sum of an empty collection is zero by default, but this is customizable:

2052
```ruby
2053 2054
[].sum    # => 0
[].sum(1) # => 1
2055
```
2056

2057
If a block is given, `sum` becomes an iterator that yields the elements of the collection and sums the returned values:
2058

2059
```ruby
2060 2061
(1..5).sum {|n| n * 2 } # => 30
[2, 4, 6, 8, 10].sum    # => 30
2062
```
2063 2064 2065

The sum of an empty receiver can be customized in this form as well:

2066
```ruby
2067
[].sum(1) {|n| n**3} # => 1
2068
```
2069

2070
NOTE: Defined in `active_support/core_ext/enumerable.rb`.
2071

2072
### `index_by`
2073

2074
The method `index_by` generates a hash with the elements of an enumerable indexed by some key.
2075 2076 2077

It iterates through the collection and passes each element to a block. The element will be keyed by the value returned by the block:

2078
```ruby
2079 2080
invoices.index_by(&:number)
# => {'2009-032' => <Invoice ...>, '2009-008' => <Invoice ...>, ...}
2081
```
2082 2083 2084

WARNING. Keys should normally be unique. If the block returns the same value for different elements no collection is built for that key. The last item will win.

2085
NOTE: Defined in `active_support/core_ext/enumerable.rb`.
2086

2087
### `many?`
2088

2089
The method `many?` is shorthand for `collection.size > 1`:
2090

2091
```erb
2092 2093 2094
<% if pages.many? %>
  <%= pagination_links %>
<% end %>
2095
```
2096

2097
If an optional block is given, `many?` only takes into account those elements that return true:
2098

2099
```ruby
2100
@see_more = videos.many? {|video| video.category == params[:category]}
2101
```
2102

2103
NOTE: Defined in `active_support/core_ext/enumerable.rb`.
2104

2105
### `exclude?`
2106

2107
The predicate `exclude?` tests whether a given object does **not** belong to the collection. It is the negation of the built-in `include?`:
2108

2109
```ruby
2110
to_visit << node if visited.exclude?(node)
2111
```
2112

2113
NOTE: Defined in `active_support/core_ext/enumerable.rb`.
2114

2115
Extensions to `Array`
2116
---------------------
2117

2118
### Accessing
2119

2120
Active Support augments the API of arrays to ease certain ways of accessing them. For example, `to` returns the subarray of elements up to the one at the passed index:
2121

2122
```ruby
2123 2124
%w(a b c d).to(2) # => %w(a b c)
[].to(7)          # => []
2125
```
2126

2127
Similarly, `from` returns the tail from the element at the passed index to the end. If the index is greater than the length of the array, it returns an empty array.
2128

2129
```ruby
2130
%w(a b c d).from(2)  # => %w(c d)
2131
%w(a b c d).from(10) # => []
X
Xavier Noria 已提交
2132
[].from(0)           # => []
2133
```
2134

2135
The methods `second`, `third`, `fourth`, and `fifth` return the corresponding element (`first` is built-in). Thanks to social wisdom and positive constructiveness all around, `forty_two` is also available.
2136

2137
```ruby
2138 2139
%w(a b c d).third # => c
%w(a b c d).fifth # => nil
2140
```
2141

2142
NOTE: Defined in `active_support/core_ext/array/access.rb`.
2143

2144
### Adding Elements
2145

2146
#### `prepend`
2147

2148
This method is an alias of `Array#unshift`.
2149

2150
```ruby
2151 2152
%w(a b c d).prepend('e')  # => %w(e a b c d)
[].prepend(10)            # => [10]
2153
```
2154

2155
NOTE: Defined in `active_support/core_ext/array/prepend_and_append.rb`.
2156

2157
#### `append`
2158

2159
This method is an alias of `Array#<<`.
2160

2161
```ruby
2162 2163
%w(a b c d).append('e')  # => %w(a b c d e)
[].append([1,2])         # => [[1,2]]
2164
```
2165

2166
NOTE: Defined in `active_support/core_ext/array/prepend_and_append.rb`.
2167

2168
### Options Extraction
2169

2170
When the last argument in a method call is a hash, except perhaps for a `&block` argument, Ruby allows you to omit the brackets:
2171

2172
```ruby
2173
User.exists?(email: params[:email])
2174
```
2175 2176 2177

That syntactic sugar is used a lot in Rails to avoid positional arguments where there would be too many, offering instead interfaces that emulate named parameters. In particular it is very idiomatic to use a trailing hash for options.

2178
If a method expects a variable number of arguments and uses `*` in its declaration, however, such an options hash ends up being an item of the array of arguments, where it loses its role.
2179

2180
In those cases, you may give an options hash a distinguished treatment with `extract_options!`. This method checks the type of the last item of an array. If it is a hash it pops it and returns it, otherwise it returns an empty hash.
2181

2182
Let's see for example the definition of the `caches_action` controller macro:
2183

2184
```ruby
2185 2186 2187 2188 2189
def caches_action(*actions)
  return unless cache_configured?
  options = actions.extract_options!
  ...
end
2190
```
2191

2192
This method receives an arbitrary number of action names, and an optional hash of options as last argument. With the call to `extract_options!` you obtain the options hash and remove it from `actions` in a simple and explicit way.
2193

2194
NOTE: Defined in `active_support/core_ext/array/extract_options.rb`.
2195

2196
### Conversions
2197

2198
#### `to_sentence`
2199

2200
The method `to_sentence` turns an array into a string containing a sentence that enumerates its items:
2201

2202
```ruby
2203 2204 2205 2206
%w().to_sentence                # => ""
%w(Earth).to_sentence           # => "Earth"
%w(Earth Wind).to_sentence      # => "Earth and Wind"
%w(Earth Wind Fire).to_sentence # => "Earth, Wind, and Fire"
2207
```
2208 2209 2210

This method accepts three options:

2211 2212 2213
* `:two_words_connector`: What is used for arrays of length 2. Default is " and ".
* `:words_connector`: What is used to join the elements of arrays with 3 or more elements, except for the last two. Default is ", ".
* `:last_word_connector`: What is used to join the last items of an array with 3 or more elements. Default is ", and ".
2214 2215 2216

The defaults for these options can be localised, their keys are:

2217 2218
| Option                 | I18n key                            |
| ---------------------- | ----------------------------------- |
2219 2220 2221
| `:two_words_connector` | `support.array.two_words_connector` |
| `:words_connector`     | `support.array.words_connector`     |
| `:last_word_connector` | `support.array.last_word_connector` |
2222

2223
Options `:connector` and `:skip_last_comma` are deprecated.
2224

2225
NOTE: Defined in `active_support/core_ext/array/conversions.rb`.
2226

2227
#### `to_formatted_s`
2228

2229
The method `to_formatted_s` acts like `to_s` by default.
2230

2231
If the array contains items that respond to `id`, however, it may be passed the symbol `:db` as argument. That's typically used with collections of ARs. Returned strings are:
2232

2233
```ruby
2234 2235 2236
[].to_formatted_s(:db)            # => "null"
[user].to_formatted_s(:db)        # => "8456"
invoice.lines.to_formatted_s(:db) # => "23,567,556,12"
2237
```
2238

2239
Integers in the example above are supposed to come from the respective calls to `id`.
2240

2241
NOTE: Defined in `active_support/core_ext/array/conversions.rb`.
2242

2243
#### `to_xml`
2244

2245
The method `to_xml` returns a string containing an XML representation of its receiver:
2246

2247
```ruby
2248
Contributor.limit(2).order(:rank).to_xml
2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264
# =>
# <?xml version="1.0" encoding="UTF-8"?>
# <contributors type="array">
#   <contributor>
#     <id type="integer">4356</id>
#     <name>Jeremy Kemper</name>
#     <rank type="integer">1</rank>
#     <url-id>jeremy-kemper</url-id>
#   </contributor>
#   <contributor>
#     <id type="integer">4404</id>
#     <name>David Heinemeier Hansson</name>
#     <rank type="integer">2</rank>
#     <url-id>david-heinemeier-hansson</url-id>
#   </contributor>
# </contributors>
2265
```
2266

2267
To do so it sends `to_xml` to every item in turn, and collects the results under a root node. All items must respond to `to_xml`, an exception is raised otherwise.
2268

2269
By default, the name of the root element is the underscorized and dasherized plural of the name of the class of the first item, provided the rest of elements belong to that type (checked with `is_a?`) and they are not hashes. In the example above that's "contributors".
2270

A
Alexey Gaziev 已提交
2271
If there's any element that does not belong to the type of the first one the root node becomes "objects":
2272

2273
```ruby
2274 2275 2276
[Contributor.first, Commit.first].to_xml
# =>
# <?xml version="1.0" encoding="UTF-8"?>
A
Alexey Gaziev 已提交
2277 2278
# <objects type="array">
#   <object>
2279 2280 2281 2282
#     <id type="integer">4583</id>
#     <name>Aaron Batalion</name>
#     <rank type="integer">53</rank>
#     <url-id>aaron-batalion</url-id>
A
Alexey Gaziev 已提交
2283 2284
#   </object>
#   <object>
2285 2286 2287 2288 2289 2290 2291 2292 2293 2294
#     <author>Joshua Peek</author>
#     <authored-timestamp type="datetime">2009-09-02T16:44:36Z</authored-timestamp>
#     <branch>origin/master</branch>
#     <committed-timestamp type="datetime">2009-09-02T16:44:36Z</committed-timestamp>
#     <committer>Joshua Peek</committer>
#     <git-show nil="true"></git-show>
#     <id type="integer">190316</id>
#     <imported-from-svn type="boolean">false</imported-from-svn>
#     <message>Kill AMo observing wrap_with_notifications since ARes was only using it</message>
#     <sha1>723a47bfb3708f968821bc969a9a3fc873a3ed58</sha1>
A
Alexey Gaziev 已提交
2295 2296
#   </object>
# </objects>
2297
```
2298

A
Alexey Gaziev 已提交
2299
If the receiver is an array of hashes the root element is by default also "objects":
2300

2301
```ruby
2302
[{a: 1, b: 2}, {c: 3}].to_xml
2303 2304
# =>
# <?xml version="1.0" encoding="UTF-8"?>
A
Alexey Gaziev 已提交
2305 2306
# <objects type="array">
#   <object>
2307 2308
#     <b type="integer">2</b>
#     <a type="integer">1</a>
A
Alexey Gaziev 已提交
2309 2310
#   </object>
#   <object>
2311
#     <c type="integer">3</c>
A
Alexey Gaziev 已提交
2312 2313
#   </object>
# </objects>
2314
```
2315

2316
WARNING. If the collection is empty the root element is by default "nil-classes". That's a gotcha, for example the root element of the list of contributors above would not be "contributors" if the collection was empty, but "nil-classes". You may use the `:root` option to ensure a consistent root element.
2317

2318
The name of children nodes is by default the name of the root node singularized. In the examples above we've seen "contributor" and "object". The option `:children` allows you to set these node names.
2319

2320
The default XML builder is a fresh instance of `Builder::XmlMarkup`. You can configure your own builder via the `:builder` option. The method also accepts options like `:dasherize` and friends, they are forwarded to the builder:
2321

2322
```ruby
2323
Contributor.limit(2).order(:rank).to_xml(skip_types: true)
2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339
# =>
# <?xml version="1.0" encoding="UTF-8"?>
# <contributors>
#   <contributor>
#     <id>4356</id>
#     <name>Jeremy Kemper</name>
#     <rank>1</rank>
#     <url-id>jeremy-kemper</url-id>
#   </contributor>
#   <contributor>
#     <id>4404</id>
#     <name>David Heinemeier Hansson</name>
#     <rank>2</rank>
#     <url-id>david-heinemeier-hansson</url-id>
#   </contributor>
# </contributors>
2340
```
2341

2342
NOTE: Defined in `active_support/core_ext/array/conversions.rb`.
2343

2344
### Wrapping
2345

2346
The method `Array.wrap` wraps its argument in an array unless it is already an array (or array-like).
2347 2348 2349

Specifically:

2350 2351
* If the argument is `nil` an empty list is returned.
* Otherwise, if the argument responds to `to_ary` it is invoked, and if the value of `to_ary` is not `nil`, it is returned.
2352
* Otherwise, an array with the argument as its single element is returned.
2353

2354
```ruby
2355 2356 2357
Array.wrap(nil)       # => []
Array.wrap([1, 2, 3]) # => [1, 2, 3]
Array.wrap(0)         # => [0]
2358
```
2359

2360
This method is similar in purpose to `Kernel#Array`, but there are some differences:
2361

2362 2363 2364
* If the argument responds to `to_ary` the method is invoked. `Kernel#Array` moves on to try `to_a` if the returned value is `nil`, but `Array.wrap` returns `nil` right away.
* If the returned value from `to_ary` is neither `nil` nor an `Array` object, `Kernel#Array` raises an exception, while `Array.wrap` does not, it just returns the value.
* It does not call `to_a` on the argument, though special-cases `nil` to return an empty array.
2365

2366
The last point is particularly worth comparing for some enumerables:
2367

2368
```ruby
2369
Array.wrap(foo: :bar) # => [{:foo=>:bar}]
2370
Array(foo: :bar)      # => [[:foo, :bar]]
2371
```
2372

2373 2374
There's also a related idiom that uses the splat operator:

2375
```ruby
2376
[*object]
2377
```
2378

2379
which in Ruby 1.8 returns `[nil]` for `nil`, and calls to `Array(object)` otherwise. (Please if you know the exact behavior in 1.9 contact fxn.)
2380

2381
Thus, in this case the behavior is different for `nil`, and the differences with `Kernel#Array` explained above apply to the rest of `object`s.
2382

2383
NOTE: Defined in `active_support/core_ext/array/wrap.rb`.
2384

2385
### Duplicating
A
Alexey Gaziev 已提交
2386

2387
The method `Array.deep_dup` duplicates itself and all objects inside recursively with ActiveSupport method `Object#deep_dup`. It works like `Array#map` with sending `deep_dup` method to each object inside.
A
Alexey Gaziev 已提交
2388

2389
```ruby
A
Alexey Gaziev 已提交
2390 2391 2392 2393
array = [1, [2, 3]]
dup = array.deep_dup
dup[1][2] = 4
array[1][2] == nil   # => true
2394
```
A
Alexey Gaziev 已提交
2395

2396
NOTE: Defined in `active_support/core_ext/array/deep_dup.rb`.
A
Alexey Gaziev 已提交
2397

2398
### Grouping
2399

2400
#### `in_groups_of(number, fill_with = nil)`
2401

2402
The method `in_groups_of` splits an array into consecutive groups of a certain size. It returns an array with the groups:
2403

2404
```ruby
2405
[1, 2, 3].in_groups_of(2) # => [[1, 2], [3, nil]]
2406
```
2407 2408 2409

or yields them in turn if a block is passed:

2410
```html+erb
2411 2412 2413 2414 2415 2416 2417
<% sample.in_groups_of(3) do |a, b, c| %>
  <tr>
    <td><%=h a %></td>
    <td><%=h b %></td>
    <td><%=h c %></td>
  </tr>
<% end %>
2418
```
2419

2420
The first example shows `in_groups_of` fills the last group with as many `nil` elements as needed to have the requested size. You can change this padding value using the second optional argument:
2421

2422
```ruby
2423
[1, 2, 3].in_groups_of(2, 0) # => [[1, 2], [3, 0]]
2424
```
2425

2426
And you can tell the method not to fill the last group passing `false`:
2427

2428
```ruby
2429
[1, 2, 3].in_groups_of(2, false) # => [[1, 2], [3]]
2430
```
2431

2432
As a consequence `false` can't be a used as a padding value.
2433

2434
NOTE: Defined in `active_support/core_ext/array/grouping.rb`.
2435

2436
#### `in_groups(number, fill_with = nil)`
2437

2438
The method `in_groups` splits an array into a certain number of groups. The method returns an array with the groups:
2439

2440
```ruby
2441 2442
%w(1 2 3 4 5 6 7).in_groups(3)
# => [["1", "2", "3"], ["4", "5", nil], ["6", "7", nil]]
2443
```
2444 2445 2446

or yields them in turn if a block is passed:

2447
```ruby
2448 2449 2450 2451
%w(1 2 3 4 5 6 7).in_groups(3) {|group| p group}
["1", "2", "3"]
["4", "5", nil]
["6", "7", nil]
2452
```
2453

2454
The examples above show that `in_groups` fills some groups with a trailing `nil` element as needed. A group can get at most one of these extra elements, the rightmost one if any. And the groups that have them are always the last ones.
2455 2456 2457

You can change this padding value using the second optional argument:

2458
```ruby
2459 2460
%w(1 2 3 4 5 6 7).in_groups(3, "0")
# => [["1", "2", "3"], ["4", "5", "0"], ["6", "7", "0"]]
2461
```
2462

2463
And you can tell the method not to fill the smaller groups passing `false`:
2464

2465
```ruby
2466 2467
%w(1 2 3 4 5 6 7).in_groups(3, false)
# => [["1", "2", "3"], ["4", "5"], ["6", "7"]]
2468
```
2469

2470
As a consequence `false` can't be a used as a padding value.
2471

2472
NOTE: Defined in `active_support/core_ext/array/grouping.rb`.
2473

2474
#### `split(value = nil)`
2475

2476
The method `split` divides an array by a separator and returns the resulting chunks.
2477 2478 2479

If a block is passed the separators are those elements of the array for which the block returns true:

2480
```ruby
2481 2482
(-5..5).to_a.split { |i| i.multiple_of?(4) }
# => [[-5], [-3, -2, -1], [1, 2, 3], [5]]
2483
```
2484

2485
Otherwise, the value received as argument, which defaults to `nil`, is the separator:
2486

2487
```ruby
2488 2489
[0, 1, -5, 1, 1, "foo", "bar"].split(1)
# => [[0], [-5], [], ["foo", "bar"]]
2490
```
2491

2492 2493
TIP: Observe in the previous example that consecutive separators result in empty arrays.

2494
NOTE: Defined in `active_support/core_ext/array/grouping.rb`.
2495

2496
Extensions to `Hash`
2497
--------------------
2498

2499
### Conversions
2500

2501
#### `to_xml`
2502

2503
The method `to_xml` returns a string containing an XML representation of its receiver:
2504

2505
```ruby
2506 2507 2508 2509 2510 2511 2512
{"foo" => 1, "bar" => 2}.to_xml
# =>
# <?xml version="1.0" encoding="UTF-8"?>
# <hash>
#   <foo type="integer">1</foo>
#   <bar type="integer">2</bar>
# </hash>
2513
```
2514

2515
To do so, the method loops over the pairs and builds nodes that depend on the _values_. Given a pair `key`, `value`:
2516

2517
* If `value` is a hash there's a recursive call with `key` as `:root`.
2518

2519
* If `value` is an array there's a recursive call with `key` as `:root`, and `key` singularized as `:children`.
2520

2521
* If `value` is a callable object it must expect one or two arguments. Depending on the arity, the callable is invoked with the `options` hash as first argument with `key` as `:root`, and `key` singularized as second argument. Its return value becomes a new node.
2522

2523
* If `value` responds to `to_xml` the method is invoked with `key` as `:root`.
2524

2525
* Otherwise, a node with `key` as tag is created with a string representation of `value` as text node. If `value` is `nil` an attribute "nil" set to "true" is added. Unless the option `:skip_types` exists and is true, an attribute "type" is added as well according to the following mapping:
2526

2527
```ruby
2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539
XML_TYPE_NAMES = {
  "Symbol"     => "symbol",
  "Fixnum"     => "integer",
  "Bignum"     => "integer",
  "BigDecimal" => "decimal",
  "Float"      => "float",
  "TrueClass"  => "boolean",
  "FalseClass" => "boolean",
  "Date"       => "date",
  "DateTime"   => "datetime",
  "Time"       => "datetime"
}
2540
```
2541

2542
By default the root node is "hash", but that's configurable via the `:root` option.
2543

2544
The default XML builder is a fresh instance of `Builder::XmlMarkup`. You can configure your own builder with the `:builder` option. The method also accepts options like `:dasherize` and friends, they are forwarded to the builder.
2545

2546
NOTE: Defined in `active_support/core_ext/hash/conversions.rb`.
2547

2548
### Merging
2549

2550
Ruby has a built-in method `Hash#merge` that merges two hashes:
2551

2552
```ruby
2553
{a: 1, b: 1}.merge(a: 0, c: 2)
2554
# => {:a=>0, :b=>1, :c=>2}
2555
```
2556 2557 2558

Active Support defines a few more ways of merging hashes that may be convenient.

2559
#### `reverse_merge` and `reverse_merge!`
2560

2561
In case of collision the key in the hash of the argument wins in `merge`. You can support option hashes with default values in a compact way with this idiom:
2562

2563
```ruby
2564
options = {length: 30, omission: "..."}.merge(options)
2565
```
2566

2567
Active Support defines `reverse_merge` in case you prefer this alternative notation:
2568

2569
```ruby
2570
options = options.reverse_merge(length: 30, omission: "...")
2571
```
2572

2573
And a bang version `reverse_merge!` that performs the merge in place:
2574

2575
```ruby
2576
options.reverse_merge!(length: 30, omission: "...")
2577
```
2578

2579
WARNING. Take into account that `reverse_merge!` may change the hash in the caller, which may or may not be a good idea.
2580

2581
NOTE: Defined in `active_support/core_ext/hash/reverse_merge.rb`.
2582

2583
#### `reverse_update`
2584

2585
The method `reverse_update` is an alias for `reverse_merge!`, explained above.
2586

2587
WARNING. Note that `reverse_update` has no bang.
2588

2589
NOTE: Defined in `active_support/core_ext/hash/reverse_merge.rb`.
2590

2591
#### `deep_merge` and `deep_merge!`
2592 2593 2594

As you can see in the previous example if a key is found in both hashes the value in the one in the argument wins.

2595
Active Support defines `Hash#deep_merge`. In a deep merge, if a key is found in both hashes and their values are hashes in turn, then their _merge_ becomes the value in the resulting hash:
2596

2597
```ruby
2598
{a: {b: 1}}.deep_merge(a: {c: 2})
2599
# => {:a=>{:b=>1, :c=>2}}
2600
```
2601

2602
The method `deep_merge!` performs a deep merge in place.
2603

2604
NOTE: Defined in `active_support/core_ext/hash/deep_merge.rb`.
2605

2606
### Deep duplicating
A
Alexey Gaziev 已提交
2607

2608
The method `Hash.deep_dup` duplicates itself and all keys and values inside recursively with ActiveSupport method `Object#deep_dup`. It works like `Enumerator#each_with_object` with sending `deep_dup` method to each pair inside.
A
Alexey Gaziev 已提交
2609

2610
```ruby
2611
hash = { a: 1, b: { c: 2, d: [3, 4] } }
A
Alexey Gaziev 已提交
2612 2613 2614 2615 2616 2617 2618

dup = hash.deep_dup
dup[:b][:e] = 5
dup[:b][:d] << 5

hash[:b][:e] == nil      # => true
hash[:b][:d] == [3, 4]   # => true
2619
```
A
Alexey Gaziev 已提交
2620

2621
NOTE: Defined in `active_support/core_ext/hash/deep_dup.rb`.
A
Alexey Gaziev 已提交
2622

2623
### Diffing
2624

2625
The method `diff` returns a hash that represents a diff of the receiver and the argument with the following logic:
2626

2627
* Pairs `key`, `value` that exist in both hashes do not belong to the diff hash.
2628

2629
* If both hashes have `key`, but with different values, the pair in the receiver wins.
2630 2631 2632

* The rest is just merged.

2633
```ruby
2634
{a: 1}.diff(a: 1)
2635 2636
# => {}, first rule

2637
{a: 1}.diff(a: 2)
2638
# => {:a=>1}, second rule
2639

2640
{a: 1}.diff(b: 2)
2641
# => {:a=>1, :b=>2}, third rule
2642

2643
{a: 1, b: 2, c: 3}.diff(b: 1, c: 3, d: 4)
2644
# => {:a=>1, :b=>2, :d=>4}, all rules
2645 2646

{}.diff({})        # => {}
2647 2648
{a: 1}.diff({})    # => {:a=>1}
{}.diff(a: 1)      # => {:a=>1}
2649
```
2650

2651
An important property of this diff hash is that you can retrieve the original hash by applying `diff` twice:
2652

2653
```ruby
2654
hash.diff(hash2).diff(hash2) == hash
2655
```
2656 2657 2658

Diffing hashes may be useful for error messages related to expected option hashes for example.

2659
NOTE: Defined in `active_support/core_ext/hash/diff.rb`.
2660

2661
### Working with Keys
2662

2663
#### `except` and `except!`
2664

2665
The method `except` returns a hash with the keys in the argument list removed, if present:
2666

2667
```ruby
2668
{a: 1, b: 2}.except(:a) # => {:b=>2}
2669
```
2670

2671
If the receiver responds to `convert_key`, the method is called on each of the arguments. This allows `except` to play nice with hashes with indifferent access for instance:
2672

2673
```ruby
2674 2675
{a: 1}.with_indifferent_access.except(:a)  # => {}
{a: 1}.with_indifferent_access.except("a") # => {}
2676
```
2677

2678
The method `except` may come in handy for example when you want to protect some parameter that can't be globally protected with `attr_protected`:
2679

2680
```ruby
2681 2682
params[:account] = params[:account].except(:plan_id) unless admin?
@account.update_attributes(params[:account])
2683
```
2684

2685
There's also the bang variant `except!` that removes keys in the very receiver.
2686

2687
NOTE: Defined in `active_support/core_ext/hash/except.rb`.
2688

2689
#### `transform_keys` and `transform_keys!`
2690

2691
The method `transform_keys` accepts a block and returns a hash that has applied the block operations to each of the keys in the receiver:
2692

2693
```ruby
2694
{nil => nil, 1 => 1, a: :a}.transform_keys{ |key| key.to_s.upcase }
2695
# => {"" => nil, "A" => :a, "1" => 1}
2696
```
2697 2698 2699

The result in case of collision is undefined:

2700
```ruby
2701
{"a" => 1, a: 2}.transform_keys{ |key| key.to_s.upcase }
2702
# => {"A" => 2}, in my test, can't rely on this result though
2703
```
2704

2705
This method may be useful for example to build specialized conversions. For instance `stringify_keys` and `symbolize_keys` use `transform_keys` to perform their key conversions:
2706

2707
```ruby
2708 2709 2710 2711 2712 2713 2714
def stringify_keys
  transform_keys{ |key| key.to_s }
end
...
def symbolize_keys
  transform_keys{ |key| key.to_sym rescue key }
end
2715
```
2716

2717
There's also the bang variant `transform_keys!` that applies the block operations to keys in the very receiver.
2718

2719
Besides that, one can use `deep_transform_keys` and `deep_transform_keys!` to perform the block operation on all the keys in the given hash and all the hashes nested into it. An example of the result is:
2720

2721
```ruby
2722
{nil => nil, 1 => 1, nested: {a: 3, 5 => 5}}.deep_transform_keys{ |key| key.to_s.upcase }
2723
# => {""=>nil, "1"=>1, "NESTED"=>{"A"=>3, "5"=>5}}
2724
```
2725

2726
NOTE: Defined in `active_support/core_ext/hash/keys.rb`.
2727

2728
#### `stringify_keys` and `stringify_keys!`
2729

2730
The method `stringify_keys` returns a hash that has a stringified version of the keys in the receiver. It does so by sending `to_s` to them:
2731

2732
```ruby
2733
{nil => nil, 1 => 1, a: :a}.stringify_keys
2734
# => {"" => nil, "a" => :a, "1" => 1}
2735
```
2736 2737 2738

The result in case of collision is undefined:

2739
```ruby
2740
{"a" => 1, a: 2}.stringify_keys
2741
# => {"a" => 2}, in my test, can't rely on this result though
2742
```
2743

2744
This method may be useful for example to easily accept both symbols and strings as options. For instance `ActionView::Helpers::FormHelper` defines:
2745

2746
```ruby
2747 2748 2749 2750 2751
def to_check_box_tag(options = {}, checked_value = "1", unchecked_value = "0")
  options = options.stringify_keys
  options["type"] = "checkbox"
  ...
end
2752
```
2753

2754
The second line can safely access the "type" key, and let the user to pass either `:type` or "type".
2755

2756
There's also the bang variant `stringify_keys!` that stringifies keys in the very receiver.
2757

2758
Besides that, one can use `deep_stringify_keys` and `deep_stringify_keys!` to stringify all the keys in the given hash and all the hashes nested into it. An example of the result is:
2759

2760
```ruby
2761
{nil => nil, 1 => 1, nested: {a: 3, 5 => 5}}.deep_stringify_keys
2762
# => {""=>nil, "1"=>1, "nested"=>{"a"=>3, "5"=>5}}
2763
```
2764

2765
NOTE: Defined in `active_support/core_ext/hash/keys.rb`.
2766

2767
#### `symbolize_keys` and `symbolize_keys!`
2768

2769
The method `symbolize_keys` returns a hash that has a symbolized version of the keys in the receiver, where possible. It does so by sending `to_sym` to them:
2770

2771
```ruby
2772
{nil => nil, 1 => 1, "a" => "a"}.symbolize_keys
2773
# => {1=>1, nil=>nil, :a=>"a"}
2774
```
2775 2776 2777 2778 2779

WARNING. Note in the previous example only one key was symbolized.

The result in case of collision is undefined:

2780
```ruby
2781
{"a" => 1, a: 2}.symbolize_keys
2782
# => {:a=>2}, in my test, can't rely on this result though
2783
```
2784

2785
This method may be useful for example to easily accept both symbols and strings as options. For instance `ActionController::UrlRewriter` defines
2786

2787
```ruby
2788 2789 2790 2791 2792
def rewrite_path(options)
  options = options.symbolize_keys
  options.update(options[:params].symbolize_keys) if options[:params]
  ...
end
2793
```
2794

2795
The second line can safely access the `:params` key, and let the user to pass either `:params` or "params".
2796

2797
There's also the bang variant `symbolize_keys!` that symbolizes keys in the very receiver.
2798

2799
Besides that, one can use `deep_symbolize_keys` and `deep_symbolize_keys!` to symbolize all the keys in the given hash and all the hashes nested into it. An example of the result is:
2800

2801
```ruby
2802
{nil => nil, 1 => 1, "nested" => {"a" => 3, 5 => 5}}.deep_symbolize_keys
2803
# => {nil=>nil, 1=>1, nested:{a:3, 5=>5}}
2804
```
2805

2806
NOTE: Defined in `active_support/core_ext/hash/keys.rb`.
2807

2808
#### `to_options` and `to_options!`
2809

2810
The methods `to_options` and `to_options!` are respectively aliases of `symbolize_keys` and `symbolize_keys!`.
2811

2812
NOTE: Defined in `active_support/core_ext/hash/keys.rb`.
2813

2814
#### `assert_valid_keys`
2815

2816
The method `assert_valid_keys` receives an arbitrary number of arguments, and checks whether the receiver has any key outside that white list. If it does `ArgumentError` is raised.
2817

2818
```ruby
2819 2820
{a: 1}.assert_valid_keys(:a)  # passes
{a: 1}.assert_valid_keys("a") # ArgumentError
2821
```
2822

2823
Active Record does not accept unknown options when building associations, for example. It implements that control via `assert_valid_keys`.
2824

2825
NOTE: Defined in `active_support/core_ext/hash/keys.rb`.
2826

2827
### Slicing
2828

2829
Ruby has built-in support for taking slices out of strings and arrays. Active Support extends slicing to hashes:
2830

2831
```ruby
2832
{a: 1, b: 2, c: 3}.slice(:a, :c)
2833
# => {:c=>3, :a=>1}
2834

2835
{a: 1, b: 2, c: 3}.slice(:b, :X)
2836
# => {:b=>2} # non-existing keys are ignored
2837
```
2838

2839
If the receiver responds to `convert_key` keys are normalized:
2840

2841
```ruby
2842
{a: 1, b: 2}.with_indifferent_access.slice("a")
2843
# => {:a=>1}
2844
```
2845 2846 2847

NOTE. Slicing may come in handy for sanitizing option hashes with a white list of keys.

2848
There's also `slice!` which in addition to perform a slice in place returns what's removed:
2849

2850
```ruby
2851
hash = {a: 1, b: 2}
2852 2853
rest = hash.slice!(:a) # => {:b=>2}
hash                   # => {:a=>1}
2854
```
2855

2856
NOTE: Defined in `active_support/core_ext/hash/slice.rb`.
2857

2858
### Extracting
S
Sebastian Martinez 已提交
2859

2860
The method `extract!` removes and returns the key/value pairs matching the given keys.
S
Sebastian Martinez 已提交
2861

2862
```ruby
2863
hash = {a: 1, b: 2}
2864 2865
rest = hash.extract!(:a) # => {:a=>1}
hash                     # => {:b=>2}
2866 2867 2868 2869 2870
```

The method `extract!` returns the same subclass of Hash, that the receiver is.

```ruby
2871
hash = {a: 1, b: 2}.with_indifferent_access
2872 2873
rest = hash.extract!(:a).class
# => ActiveSupport::HashWithIndifferentAccess
2874
```
S
Sebastian Martinez 已提交
2875

2876
NOTE: Defined in `active_support/core_ext/hash/slice.rb`.
S
Sebastian Martinez 已提交
2877

2878
### Indifferent Access
2879

2880
The method `with_indifferent_access` returns an `ActiveSupport::HashWithIndifferentAccess` out of its receiver:
2881

2882
```ruby
2883
{a: 1}.with_indifferent_access["a"] # => 1
2884
```
2885

2886
NOTE: Defined in `active_support/core_ext/hash/indifferent_access.rb`.
2887

2888
Extensions to `Regexp`
2889
----------------------
2890

2891
### `multiline?`
2892

2893
The method `multiline?` says whether a regexp has the `/m` flag set, that is, whether the dot matches newlines.
2894

2895
```ruby
2896 2897 2898 2899 2900
%r{.}.multiline?  # => false
%r{.}m.multiline? # => true

Regexp.new('.').multiline?                    # => false
Regexp.new('.', Regexp::MULTILINE).multiline? # => true
2901
```
2902 2903 2904

Rails uses this method in a single place, also in the routing code. Multiline regexps are disallowed for route requirements and this flag eases enforcing that constraint.

2905
```ruby
2906 2907 2908 2909 2910 2911 2912
def assign_route_options(segments, defaults, requirements)
  ...
  if requirement.multiline?
    raise ArgumentError, "Regexp multiline option not allowed in routing requirements: #{requirement.inspect}"
  end
  ...
end
2913
```
2914

2915
NOTE: Defined in `active_support/core_ext/regexp.rb`.
2916

2917
Extensions to `Range`
2918
---------------------
2919

2920
### `to_s`
2921

2922
Active Support extends the method `Range#to_s` so that it understands an optional format argument. As of this writing the only supported non-default format is `:db`:
2923

2924
```ruby
2925 2926 2927 2928 2929
(Date.today..Date.tomorrow).to_s
# => "2009-10-25..2009-10-26"

(Date.today..Date.tomorrow).to_s(:db)
# => "BETWEEN '2009-10-25' AND '2009-10-26'"
2930
```
2931

2932
As the example depicts, the `:db` format generates a `BETWEEN` SQL clause. That is used by Active Record in its support for range values in conditions.
2933

2934
NOTE: Defined in `active_support/core_ext/range/conversions.rb`.
2935

2936
### `include?`
2937

2938
The methods `Range#include?` and `Range#===` say whether some value falls between the ends of a given instance:
2939

2940
```ruby
2941
(2..3).include?(Math::E) # => true
2942
```
2943

A
Alexey Gaziev 已提交
2944
Active Support extends these methods so that the argument may be another range in turn. In that case we test whether the ends of the argument range belong to the receiver themselves:
2945

2946
```ruby
2947 2948 2949 2950 2951
(1..10).include?(3..7)  # => true
(1..10).include?(0..7)  # => false
(1..10).include?(3..11) # => false
(1...9).include?(3..9)  # => false

A
Alexey Gaziev 已提交
2952 2953 2954 2955
(1..10) === (3..7)  # => true
(1..10) === (0..7)  # => false
(1..10) === (3..11) # => false
(1...9) === (3..9)  # => false
2956
```
2957

2958
NOTE: Defined in `active_support/core_ext/range/include_range.rb`.
2959

2960
### `overlaps?`
2961

2962
The method `Range#overlaps?` says whether any two given ranges have non-void intersection:
2963

2964
```ruby
2965 2966 2967
(1..10).overlaps?(7..11)  # => true
(1..10).overlaps?(0..7)   # => true
(1..10).overlaps?(11..27) # => false
2968
```
2969

2970
NOTE: Defined in `active_support/core_ext/range/overlaps.rb`.
2971

2972
Extensions to `Proc`
2973
--------------------
2974

2975
### `bind`
X
Xavier Noria 已提交
2976

2977
As you surely know Ruby has an `UnboundMethod` class whose instances are methods that belong to the limbo of methods without a self. The method `Module#instance_method` returns an unbound method for example:
X
Xavier Noria 已提交
2978

2979
```ruby
X
Xavier Noria 已提交
2980
Hash.instance_method(:delete) # => #<UnboundMethod: Hash#delete>
2981
```
X
Xavier Noria 已提交
2982

2983
An unbound method is not callable as is, you need to bind it first to an object with `bind`:
X
Xavier Noria 已提交
2984

2985
```ruby
X
Xavier Noria 已提交
2986
clear = Hash.instance_method(:clear)
2987
clear.bind({a: 1}).call # => {}
2988
```
X
Xavier Noria 已提交
2989

2990
Active Support defines `Proc#bind` with an analogous purpose:
X
Xavier Noria 已提交
2991

2992
```ruby
X
Xavier Noria 已提交
2993
Proc.new { size }.bind([]).call # => 0
2994
```
X
Xavier Noria 已提交
2995

2996
As you see that's callable and bound to the argument, the return value is indeed a `Method`.
X
Xavier Noria 已提交
2997

2998
NOTE: To do so `Proc#bind` actually creates a method under the hood. If you ever see a method with a weird name like `__bind_1256598120_237302` in a stack trace you know now where it comes from.
X
Xavier Noria 已提交
2999

3000
Action Pack uses this trick in `rescue_from` for example, which accepts the name of a method and also a proc as callbacks for a given rescued exception. It has to call them in either case, so a bound method is returned by `handler_for_rescue`, thus simplifying the code in the caller:
X
Xavier Noria 已提交
3001

3002
```ruby
X
Xavier Noria 已提交
3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014
def handler_for_rescue(exception)
  _, rescuer = Array(rescue_handlers).reverse.detect do |klass_name, handler|
    ...
  end

  case rescuer
  when Symbol
    method(rescuer)
  when Proc
    rescuer.bind(self)
  end
end
3015
```
3016

3017
NOTE: Defined in `active_support/core_ext/proc.rb`.
3018

3019
Extensions to `Date`
3020
--------------------
3021

3022
### Calculations
3023

3024
NOTE: All the following methods are defined in `active_support/core_ext/date/calculations.rb`.
3025

3026
INFO: The following calculation methods have edge cases in October 1582, since days 5..14 just do not exist. This guide does not document their behavior around those days for brevity, but it is enough to say that they do what you would expect. That is, `Date.new(1582, 10, 4).tomorrow` returns `Date.new(1582, 10, 15)` and so on. Please check `test/core_ext/date_ext_test.rb` in the Active Support test suite for expected behavior.
3027

3028
#### `Date.current`
3029

3030
Active Support defines `Date.current` to be today in the current time zone. That's like `Date.today`, except that it honors the user time zone, if defined. It also defines `Date.yesterday` and `Date.tomorrow`, and the instance predicates `past?`, `today?`, and `future?`, all of them relative to `Date.current`.
3031

3032
When making Date comparisons using methods which honor the user time zone, make sure to use `Date.current` and not `Date.today`. There are cases where the user time zone might be in the future compared to the system time zone, which `Date.today` uses by default. This means `Date.today` may equal `Date.yesterday`.
3033

3034
#### Named dates
3035

3036
##### `prev_year`, `next_year`
3037

3038
In Ruby 1.9 `prev_year` and `next_year` return a date with the same day/month in the last or next year:
3039

3040
```ruby
3041
d = Date.new(2010, 5, 8) # => Sat, 08 May 2010
3042
d.prev_year              # => Fri, 08 May 2009
3043
d.next_year              # => Sun, 08 May 2011
3044
```
3045 3046 3047

If date is the 29th of February of a leap year, you obtain the 28th:

3048
```ruby
3049
d = Date.new(2000, 2, 29) # => Tue, 29 Feb 2000
3050
d.prev_year               # => Sun, 28 Feb 1999
3051
d.next_year               # => Wed, 28 Feb 2001
3052
```
3053

3054
`prev_year` is aliased to `last_year`.
3055

3056
##### `prev_month`, `next_month`
3057

3058
In Ruby 1.9 `prev_month` and `next_month` return the date with the same day in the last or next month:
3059

3060
```ruby
3061
d = Date.new(2010, 5, 8) # => Sat, 08 May 2010
3062
d.prev_month             # => Thu, 08 Apr 2010
3063
d.next_month             # => Tue, 08 Jun 2010
3064
```
3065 3066 3067

If such a day does not exist, the last day of the corresponding month is returned:

3068
```ruby
3069 3070
Date.new(2000, 5, 31).prev_month # => Sun, 30 Apr 2000
Date.new(2000, 3, 31).prev_month # => Tue, 29 Feb 2000
3071 3072
Date.new(2000, 5, 31).next_month # => Fri, 30 Jun 2000
Date.new(2000, 1, 31).next_month # => Tue, 29 Feb 2000
3073
```
3074

3075
`prev_month` is aliased to `last_month`.
3076

3077
##### `prev_quarter`, `next_quarter`
3078

3079
Same as `prev_month` and `next_month`. It returns the date with the same day in the previous or next quarter:
3080

3081
```ruby
3082 3083 3084
t = Time.local(2010, 5, 8) # => Sat, 08 May 2010
t.prev_quarter             # => Mon, 08 Feb 2010
t.next_quarter             # => Sun, 08 Aug 2010
3085
```
3086 3087 3088

If such a day does not exist, the last day of the corresponding month is returned:

3089
```ruby
3090 3091 3092 3093
Time.local(2000, 7, 31).prev_quarter  # => Sun, 30 Apr 2000
Time.local(2000, 5, 31).prev_quarter  # => Tue, 29 Feb 2000
Time.local(2000, 10, 31).prev_quarter # => Mon, 30 Oct 2000
Time.local(2000, 11, 31).next_quarter # => Wed, 28 Feb 2001
3094
```
3095

3096
`prev_quarter` is aliased to `last_quarter`.
3097

3098
##### `beginning_of_week`, `end_of_week`
3099

3100
The methods `beginning_of_week` and `end_of_week` return the dates for the
3101
beginning and end of the week, respectively. Weeks are assumed to start on
3102 3103
Monday, but that can be changed passing an argument, setting thread local
`Date.beginning_of_week` or `config.beginning_of_week`.
3104

3105
```ruby
3106 3107 3108 3109 3110
d = Date.new(2010, 5, 8)     # => Sat, 08 May 2010
d.beginning_of_week          # => Mon, 03 May 2010
d.beginning_of_week(:sunday) # => Sun, 02 May 2010
d.end_of_week                # => Sun, 09 May 2010
d.end_of_week(:sunday)       # => Sat, 08 May 2010
3111
```
3112

3113
`beginning_of_week` is aliased to `at_beginning_of_week` and `end_of_week` is aliased to `at_end_of_week`.
3114

3115
##### `monday`, `sunday`
V
Vijay Dev 已提交
3116

3117 3118
The methods `monday` and `sunday` return the dates for the previous Monday and
next Sunday, respectively.
V
Vijay Dev 已提交
3119

3120
```ruby
V
Vijay Dev 已提交
3121 3122 3123
d = Date.new(2010, 5, 8)     # => Sat, 08 May 2010
d.monday                     # => Mon, 03 May 2010
d.sunday                     # => Sun, 09 May 2010
3124 3125 3126 3127 3128 3129

d = Date.new(2012, 9, 10)    # => Mon, 10 Sep 2012
d.monday                     # => Mon, 10 Sep 2012

d = Date.new(2012, 9, 16)    # => Sun, 16 Sep 2012
d.sunday                     # => Sun, 16 Sep 2012
3130
```
V
Vijay Dev 已提交
3131

3132
##### `prev_week`, `next_week`
3133

X
Xavier Noria 已提交
3134
The method `next_week` receives a symbol with a day name in English (default is the thread local `Date.beginning_of_week`, or `config.beginning_of_week`, or `:monday`) and it returns the date corresponding to that day.
3135

3136
```ruby
3137 3138 3139
d = Date.new(2010, 5, 9) # => Sun, 09 May 2010
d.next_week              # => Mon, 10 May 2010
d.next_week(:saturday)   # => Sat, 15 May 2010
3140
```
3141

3142
The method `prev_week` is analogous:
3143

3144
```ruby
3145 3146 3147
d.prev_week              # => Mon, 26 Apr 2010
d.prev_week(:saturday)   # => Sat, 01 May 2010
d.prev_week(:friday)     # => Fri, 30 Apr 2010
3148
```
3149

3150
`prev_week` is aliased to `last_week`.
X
Xavier Noria 已提交
3151 3152

Both `next_week` and `prev_week` work as expected when `Date.beginning_of_week` or `config.beginning_of_week` are set.
3153

3154
##### `beginning_of_month`, `end_of_month`
3155

3156
The methods `beginning_of_month` and `end_of_month` return the dates for the beginning and end of the month:
3157

3158
```ruby
3159 3160 3161
d = Date.new(2010, 5, 9) # => Sun, 09 May 2010
d.beginning_of_month     # => Sat, 01 May 2010
d.end_of_month           # => Mon, 31 May 2010
3162
```
3163

3164
`beginning_of_month` is aliased to `at_beginning_of_month`, and `end_of_month` is aliased to `at_end_of_month`.
3165

3166
##### `beginning_of_quarter`, `end_of_quarter`
3167

3168
The methods `beginning_of_quarter` and `end_of_quarter` return the dates for the beginning and end of the quarter of the receiver's calendar year:
3169

3170
```ruby
3171 3172 3173
d = Date.new(2010, 5, 9) # => Sun, 09 May 2010
d.beginning_of_quarter   # => Thu, 01 Apr 2010
d.end_of_quarter         # => Wed, 30 Jun 2010
3174
```
3175

3176
`beginning_of_quarter` is aliased to `at_beginning_of_quarter`, and `end_of_quarter` is aliased to `at_end_of_quarter`.
3177

3178
##### `beginning_of_year`, `end_of_year`
3179

3180
The methods `beginning_of_year` and `end_of_year` return the dates for the beginning and end of the year:
3181

3182
```ruby
3183 3184 3185
d = Date.new(2010, 5, 9) # => Sun, 09 May 2010
d.beginning_of_year      # => Fri, 01 Jan 2010
d.end_of_year            # => Fri, 31 Dec 2010
3186
```
3187

3188
`beginning_of_year` is aliased to `at_beginning_of_year`, and `end_of_year` is aliased to `at_end_of_year`.
3189

3190
#### Other Date Computations
3191

3192
##### `years_ago`, `years_since`
3193

3194
The method `years_ago` receives a number of years and returns the same date those many years ago:
3195

3196
```ruby
3197 3198
date = Date.new(2010, 6, 7)
date.years_ago(10) # => Wed, 07 Jun 2000
3199
```
3200

3201
`years_since` moves forward in time:
3202

3203
```ruby
3204 3205
date = Date.new(2010, 6, 7)
date.years_since(10) # => Sun, 07 Jun 2020
3206
```
3207 3208 3209

If such a day does not exist, the last day of the corresponding month is returned:

3210
```ruby
3211 3212
Date.new(2012, 2, 29).years_ago(3)     # => Sat, 28 Feb 2009
Date.new(2012, 2, 29).years_since(3)   # => Sat, 28 Feb 2015
3213
```
3214

3215
##### `months_ago`, `months_since`
3216

3217
The methods `months_ago` and `months_since` work analogously for months:
3218

3219
```ruby
3220 3221
Date.new(2010, 4, 30).months_ago(2)   # => Sun, 28 Feb 2010
Date.new(2010, 4, 30).months_since(2) # => Wed, 30 Jun 2010
3222
```
3223 3224 3225

If such a day does not exist, the last day of the corresponding month is returned:

3226
```ruby
3227 3228
Date.new(2010, 4, 30).months_ago(2)    # => Sun, 28 Feb 2010
Date.new(2009, 12, 31).months_since(2) # => Sun, 28 Feb 2010
3229
```
3230

3231
##### `weeks_ago`
3232

3233
The method `weeks_ago` works analogously for weeks:
3234

3235
```ruby
3236 3237
Date.new(2010, 5, 24).weeks_ago(1)    # => Mon, 17 May 2010
Date.new(2010, 5, 24).weeks_ago(2)    # => Mon, 10 May 2010
3238
```
3239

3240
##### `advance`
3241

3242
The most generic way to jump to other days is `advance`. This method receives a hash with keys `:years`, `:months`, `:weeks`, `:days`, and returns a date advanced as much as the present keys indicate:
3243

3244
```ruby
3245
date = Date.new(2010, 6, 6)
3246 3247
date.advance(years: 1, weeks: 2)  # => Mon, 20 Jun 2011
date.advance(months: 2, days: -2) # => Wed, 04 Aug 2010
3248
```
3249 3250 3251 3252 3253

Note in the previous example that increments may be negative.

To perform the computation the method first increments years, then months, then weeks, and finally days. This order is important towards the end of months. Say for example we are at the end of February of 2010, and we want to move one month and one day forward.

3254
The method `advance` advances first one month, and then one day, the result is:
3255

3256
```ruby
3257
Date.new(2010, 2, 28).advance(months: 1, days: 1)
3258
# => Sun, 29 Mar 2010
3259
```
3260 3261 3262

While if it did it the other way around the result would be different:

3263
```ruby
3264
Date.new(2010, 2, 28).advance(days: 1).advance(months: 1)
3265
# => Thu, 01 Apr 2010
3266
```
3267

3268
#### Changing Components
3269

3270
The method `change` allows you to get a new date which is the same as the receiver except for the given year, month, or day:
3271

3272
```ruby
3273
Date.new(2010, 12, 23).change(year: 2011, month: 11)
3274
# => Wed, 23 Nov 2011
3275
```
3276

3277
This method is not tolerant to non-existing dates, if the change is invalid `ArgumentError` is raised:
3278

3279
```ruby
3280
Date.new(2010, 1, 31).change(month: 2)
3281
# => ArgumentError: invalid date
3282
```
3283

3284
#### Durations
3285

E
Evan Farrar 已提交
3286
Durations can be added to and subtracted from dates:
3287

3288
```ruby
3289 3290 3291 3292 3293 3294
d = Date.current
# => Mon, 09 Aug 2010
d + 1.year
# => Tue, 09 Aug 2011
d - 3.hours
# => Sun, 08 Aug 2010 21:00:00 UTC +00:00
3295
```
3296

3297
They translate to calls to `since` or `advance`. For example here we get the correct jump in the calendar reform:
3298

3299
```ruby
3300 3301
Date.new(1582, 10, 4) + 1.day
# => Fri, 15 Oct 1582
3302
```
3303

3304
#### Timestamps
3305

3306
INFO: The following methods return a `Time` object if possible, otherwise a `DateTime`. If set, they honor the user time zone.
3307

3308
##### `beginning_of_day`, `end_of_day`
3309

3310
The method `beginning_of_day` returns a timestamp at the beginning of the day (00:00:00):
3311

3312
```ruby
3313
date = Date.new(2010, 6, 7)
3314
date.beginning_of_day # => Mon Jun 07 00:00:00 +0200 2010
3315
```
3316

3317
The method `end_of_day` returns a timestamp at the end of the day (23:59:59):
3318

3319
```ruby
3320
date = Date.new(2010, 6, 7)
3321
date.end_of_day # => Mon Jun 07 23:59:59 +0200 2010
3322
```
3323

3324
`beginning_of_day` is aliased to `at_beginning_of_day`, `midnight`, `at_midnight`.
3325

3326
##### `beginning_of_hour`, `end_of_hour`
3327

3328
The method `beginning_of_hour` returns a timestamp at the beginning of the hour (hh:00:00):
3329

3330
```ruby
3331 3332
date = DateTime.new(2010, 6, 7, 19, 55, 25)
date.beginning_of_hour # => Mon Jun 07 19:00:00 +0200 2010
3333
```
3334

3335
The method `end_of_hour` returns a timestamp at the end of the hour (hh:59:59):
3336

3337
```ruby
3338 3339
date = DateTime.new(2010, 6, 7, 19, 55, 25)
date.end_of_hour # => Mon Jun 07 19:59:59 +0200 2010
3340
```
3341

3342
`beginning_of_hour` is aliased to `at_beginning_of_hour`.
3343

3344
INFO: `beginning_of_hour` and `end_of_hour` are implemented for `Time` and `DateTime` but **not** `Date` as it does not make sense to request the beginning or end of an hour on a `Date` instance.
3345

3346
##### `ago`, `since`
3347

3348
The method `ago` receives a number of seconds as argument and returns a timestamp those many seconds ago from midnight:
3349

3350
```ruby
3351
date = Date.current # => Fri, 11 Jun 2010
3352
date.ago(1)         # => Thu, 10 Jun 2010 23:59:59 EDT -04:00
3353
```
3354

3355
Similarly, `since` moves forward:
3356

3357
```ruby
3358
date = Date.current # => Fri, 11 Jun 2010
3359
date.since(1)       # => Fri, 11 Jun 2010 00:00:01 EDT -04:00
3360
```
3361

3362
#### Other Time Computations
3363

3364
### Conversions
3365

3366
Extensions to `DateTime`
3367
------------------------
3368

3369
WARNING: `DateTime` is not aware of DST rules and so some of these methods have edge cases when a DST change is going on. For example `seconds_since_midnight` might not return the real amount in such a day.
3370

3371
### Calculations
3372

3373
NOTE: All the following methods are defined in `active_support/core_ext/date_time/calculations.rb`.
3374

3375
The class `DateTime` is a subclass of `Date` so by loading `active_support/core_ext/date/calculations.rb` you inherit these methods and their aliases, except that they will always return datetimes:
3376

3377
```ruby
3378 3379
yesterday
tomorrow
3380
beginning_of_week (at_beginning_of_week)
V
Vijay Dev 已提交
3381
end_of_week (at_end_of_week)
3382 3383
monday
sunday
3384
weeks_ago
3385
prev_week (last_week)
3386 3387 3388
next_week
months_ago
months_since
3389 3390
beginning_of_month (at_beginning_of_month)
end_of_month (at_end_of_month)
3391
prev_month (last_month)
3392
next_month
3393 3394 3395 3396
beginning_of_quarter (at_beginning_of_quarter)
end_of_quarter (at_end_of_quarter)
beginning_of_year (at_beginning_of_year)
end_of_year (at_end_of_year)
3397 3398
years_ago
years_since
3399
prev_year (last_year)
3400
next_year
3401
```
3402

3403
The following methods are reimplemented so you do **not** need to load `active_support/core_ext/date/calculations.rb` for these ones:
3404

3405
```ruby
3406
beginning_of_day (midnight, at_midnight, at_beginning_of_day)
3407 3408
end_of_day
ago
3409
since (in)
3410
```
3411

3412
On the other hand, `advance` and `change` are also defined and support more options, they are documented below.
3413

3414
The following methods are only implemented in `active_support/core_ext/date_time/calculations.rb` as they only make sense when used with a `DateTime` instance:
3415

3416
```ruby
3417 3418
beginning_of_hour (at_beginning_of_hour)
end_of_hour
3419
```
3420

3421
#### Named Datetimes
3422

3423
##### `DateTime.current`
3424

3425
Active Support defines `DateTime.current` to be like `Time.now.to_datetime`, except that it honors the user time zone, if defined. It also defines `DateTime.yesterday` and `DateTime.tomorrow`, and the instance predicates `past?`, and `future?` relative to `DateTime.current`.
3426

3427
#### Other Extensions
3428

3429
##### `seconds_since_midnight`
3430

3431
The method `seconds_since_midnight` returns the number of seconds since midnight:
3432

3433
```ruby
3434 3435
now = DateTime.current     # => Mon, 07 Jun 2010 20:26:36 +0000
now.seconds_since_midnight # => 73596
3436
```
3437

3438
##### `utc`
3439

3440
The method `utc` gives you the same datetime in the receiver expressed in UTC.
3441

3442
```ruby
3443 3444
now = DateTime.current # => Mon, 07 Jun 2010 19:27:52 -0400
now.utc                # => Mon, 07 Jun 2010 23:27:52 +0000
3445
```
3446

3447
This method is also aliased as `getutc`.
3448

3449
##### `utc?`
3450

3451
The predicate `utc?` says whether the receiver has UTC as its time zone:
3452

3453
```ruby
3454 3455 3456
now = DateTime.now # => Mon, 07 Jun 2010 19:30:47 -0400
now.utc?           # => false
now.utc.utc?       # => true
3457
```
3458

3459
##### `advance`
3460

3461
The most generic way to jump to another datetime is `advance`. This method receives a hash with keys `:years`, `:months`, `:weeks`, `:days`, `:hours`, `:minutes`, and `:seconds`, and returns a datetime advanced as much as the present keys indicate.
3462

3463
```ruby
3464 3465
d = DateTime.current
# => Thu, 05 Aug 2010 11:33:31 +0000
3466
d.advance(years: 1, months: 1, days: 1, hours: 1, minutes: 1, seconds: 1)
3467
# => Tue, 06 Sep 2011 12:34:32 +0000
3468
```
3469

3470
This method first computes the destination date passing `:years`, `:months`, `:weeks`, and `:days` to `Date#advance` documented above. After that, it adjusts the time calling `since` with the number of seconds to advance. This order is relevant, a different ordering would give different datetimes in some edge-cases. The example in `Date#advance` applies, and we can extend it to show order relevance related to the time bits.
3471 3472 3473

If we first move the date bits (that have also a relative order of processing, as documented before), and then the time bits we get for example the following computation:

3474
```ruby
3475 3476
d = DateTime.new(2010, 2, 28, 23, 59, 59)
# => Sun, 28 Feb 2010 23:59:59 +0000
3477
d.advance(months: 1, seconds: 1)
3478
# => Mon, 29 Mar 2010 00:00:00 +0000
3479
```
3480 3481 3482

but if we computed them the other way around, the result would be different:

3483
```ruby
3484
d.advance(seconds: 1).advance(months: 1)
3485
# => Thu, 01 Apr 2010 00:00:00 +0000
3486
```
3487

3488
WARNING: Since `DateTime` is not DST-aware you can end up in a non-existing point in time with no warning or error telling you so.
3489

3490
#### Changing Components
3491

3492
The method `change` allows you to get a new datetime which is the same as the receiver except for the given options, which may include `:year`, `:month`, `:day`, `:hour`, `:min`, `:sec`, `:offset`, `:start`:
3493

3494
```ruby
3495 3496
now = DateTime.current
# => Tue, 08 Jun 2010 01:56:22 +0000
3497
now.change(year: 2011, offset: Rational(-6, 24))
3498
# => Wed, 08 Jun 2011 01:56:22 -0600
3499
```
3500 3501 3502

If hours are zeroed, then minutes and seconds are too (unless they have given values):

3503
```ruby
3504
now.change(hour: 0)
3505
# => Tue, 08 Jun 2010 00:00:00 +0000
3506
```
3507 3508 3509

Similarly, if minutes are zeroed, then seconds are too (unless it has given a value):

3510
```ruby
3511
now.change(min: 0)
3512
# => Tue, 08 Jun 2010 01:00:00 +0000
3513
```
3514

3515
This method is not tolerant to non-existing dates, if the change is invalid `ArgumentError` is raised:
3516

3517
```ruby
3518
DateTime.current.change(month: 2, day: 30)
3519
# => ArgumentError: invalid date
3520
```
3521

3522
#### Durations
3523

E
Evan Farrar 已提交
3524
Durations can be added to and subtracted from datetimes:
3525

3526
```ruby
3527 3528 3529 3530 3531 3532
now = DateTime.current
# => Mon, 09 Aug 2010 23:15:17 +0000
now + 1.year
# => Tue, 09 Aug 2011 23:15:17 +0000
now - 1.week
# => Mon, 02 Aug 2010 23:15:17 +0000
3533
```
3534

3535
They translate to calls to `since` or `advance`. For example here we get the correct jump in the calendar reform:
3536

3537
```ruby
3538 3539
DateTime.new(1582, 10, 4, 23) + 1.hour
# => Fri, 15 Oct 1582 00:00:00 +0000
3540
```
3541

3542
Extensions to `Time`
3543
--------------------
3544

3545
### Calculations
3546

3547
NOTE: All the following methods are defined in `active_support/core_ext/time/calculations.rb`.
3548

3549
Active Support adds to `Time` many of the methods available for `DateTime`:
3550

3551
```ruby
3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563
past?
today?
future?
yesterday
tomorrow
seconds_since_midnight
change
advance
ago
since (in)
beginning_of_day (midnight, at_midnight, at_beginning_of_day)
end_of_day
3564 3565
beginning_of_hour (at_beginning_of_hour)
end_of_hour
3566
beginning_of_week (at_beginning_of_week)
V
Vijay Dev 已提交
3567
end_of_week (at_end_of_week)
3568
monday
V
Vijay Dev 已提交
3569
sunday
3570
weeks_ago
3571
prev_week (last_week)
3572 3573 3574 3575 3576
next_week
months_ago
months_since
beginning_of_month (at_beginning_of_month)
end_of_month (at_end_of_month)
3577
prev_month (last_month)
3578 3579 3580 3581 3582 3583 3584
next_month
beginning_of_quarter (at_beginning_of_quarter)
end_of_quarter (at_end_of_quarter)
beginning_of_year (at_beginning_of_year)
end_of_year (at_end_of_year)
years_ago
years_since
3585
prev_year (last_year)
3586
next_year
3587
```
3588 3589 3590

They are analogous. Please refer to their documentation above and take into account the following differences:

3591 3592
* `change` accepts an additional `:usec` option.
* `Time` understands DST, so you get correct DST calculations as in
3593

3594
```ruby
3595 3596 3597
Time.zone_default
# => #<ActiveSupport::TimeZone:0x7f73654d4f38 @utc_offset=nil, @name="Madrid", ...>

3598
# In Barcelona, 2010/03/28 02:00 +0100 becomes 2010/03/28 03:00 +0200 due to DST.
3599
t = Time.local_time(2010, 3, 28, 1, 59, 59)
V
Vijay Dev 已提交
3600
# => Sun Mar 28 01:59:59 +0100 2010
3601
t.advance(seconds: 1)
V
Vijay Dev 已提交
3602
# => Sun Mar 28 03:00:00 +0200 2010
3603
```
3604

3605
* If `since` or `ago` jump to a time that can't be expressed with `Time` a `DateTime` object is returned instead.
3606

3607
#### `Time.current`
3608

3609
Active Support defines `Time.current` to be today in the current time zone. That's like `Time.now`, except that it honors the user time zone, if defined. It also defines `Time.yesterday` and `Time.tomorrow`, and the instance predicates `past?`, `today?`, and `future?`, all of them relative to `Time.current`.
3610

3611
When making Time comparisons using methods which honor the user time zone, make sure to use `Time.current` and not `Time.now`. There are cases where the user time zone might be in the future compared to the system time zone, which `Time.today` uses by default. This means `Time.now` may equal `Time.yesterday`.
3612

3613
#### `all_day`, `all_week`, `all_month`, `all_quarter` and `all_year`
3614

3615
The method `all_day` returns a range representing the whole day of the current time.
3616

3617
```ruby
3618
now = Time.current
V
Vijay Dev 已提交
3619
# => Mon, 09 Aug 2010 23:20:05 UTC +00:00
3620
now.all_day
3621
# => Mon, 09 Aug 2010 00:00:00 UTC +00:00..Mon, 09 Aug 2010 23:59:59 UTC +00:00
3622
```
3623

3624
Analogously, `all_week`, `all_month`, `all_quarter` and `all_year` all serve the purpose of generating time ranges.
3625

3626
```ruby
3627
now = Time.current
V
Vijay Dev 已提交
3628
# => Mon, 09 Aug 2010 23:20:05 UTC +00:00
3629
now.all_week
3630
# => Mon, 09 Aug 2010 00:00:00 UTC +00:00..Sun, 15 Aug 2010 23:59:59 UTC +00:00
3631 3632
now.all_week(:sunday)
# => Sun, 16 Sep 2012 00:00:00 UTC +00:00..Sat, 22 Sep 2012 23:59:59 UTC +00:00
3633
now.all_month
3634
# => Sat, 01 Aug 2010 00:00:00 UTC +00:00..Tue, 31 Aug 2010 23:59:59 UTC +00:00
3635
now.all_quarter
3636
# => Thu, 01 Jul 2010 00:00:00 UTC +00:00..Thu, 30 Sep 2010 23:59:59 UTC +00:00
3637
now.all_year
3638
# => Fri, 01 Jan 2010 00:00:00 UTC +00:00..Fri, 31 Dec 2010 23:59:59 UTC +00:00
3639
```
3640

3641
### Time Constructors
3642

3643
Active Support defines `Time.current` to be `Time.zone.now` if there's a user time zone defined, with fallback to `Time.now`:
3644

3645
```ruby
3646 3647 3648
Time.zone_default
# => #<ActiveSupport::TimeZone:0x7f73654d4f38 @utc_offset=nil, @name="Madrid", ...>
Time.current
V
Vijay Dev 已提交
3649
# => Fri, 06 Aug 2010 17:11:58 CEST +02:00
3650
```
3651

3652
Analogously to `DateTime`, the predicates `past?`, and `future?` are relative to `Time.current`.
3653

3654
Use the `local_time` class method to create time objects honoring the user time zone:
3655

3656
```ruby
3657 3658 3659
Time.zone_default
# => #<ActiveSupport::TimeZone:0x7f73654d4f38 @utc_offset=nil, @name="Madrid", ...>
Time.local_time(2010, 8, 15)
V
Vijay Dev 已提交
3660
# => Sun Aug 15 00:00:00 +0200 2010
3661
```
3662

3663
The `utc_time` class method returns a time in UTC:
3664

3665
```ruby
3666 3667 3668 3669
Time.zone_default
# => #<ActiveSupport::TimeZone:0x7f73654d4f38 @utc_offset=nil, @name="Madrid", ...>
Time.utc_time(2010, 8, 15)
# => Sun Aug 15 00:00:00 UTC 2010
3670
```
3671

3672
Both `local_time` and `utc_time` accept up to seven positional arguments: year, month, day, hour, min, sec, usec. Year is mandatory, month and day default to 1, and the rest default to 0.
3673

3674
If the time to be constructed lies beyond the range supported by `Time` in the runtime platform, usecs are discarded and a `DateTime` object is returned instead.
3675

3676
#### Durations
3677

E
Evan Farrar 已提交
3678
Durations can be added to and subtracted from time objects:
3679

3680
```ruby
3681 3682 3683 3684 3685 3686
now = Time.current
# => Mon, 09 Aug 2010 23:20:05 UTC +00:00
now + 1.year
#  => Tue, 09 Aug 2011 23:21:11 UTC +00:00
now - 1.week
# => Mon, 02 Aug 2010 23:21:11 UTC +00:00
3687
```
3688

3689
They translate to calls to `since` or `advance`. For example here we get the correct jump in the calendar reform:
3690

3691
```ruby
3692 3693
Time.utc_time(1582, 10, 3) + 5.days
# => Mon Oct 18 00:00:00 UTC 1582
3694
```
3695

3696
Extensions to `File`
3697
--------------------
3698

3699
### `atomic_write`
3700

3701
With the class method `File.atomic_write` you can write to a file in a way that will prevent any reader from seeing half-written content.
3702

3703
The name of the file is passed as an argument, and the method yields a file handle opened for writing. Once the block is done `atomic_write` closes the file handle and completes its job.
3704

3705
For example, Action Pack uses this method to write asset cache files like `all.css`:
3706

3707
```ruby
3708 3709 3710
File.atomic_write(joined_asset_path) do |cache|
  cache.write(join_asset_file_contents(asset_paths))
end
3711
```
3712

3713 3714 3715
To accomplish this `atomic_write` creates a temporary file. That's the file the code in the block actually writes to. On completion, the temporary file is renamed, which is an atomic operation on POSIX systems. If the target file exists `atomic_write` overwrites it and keeps owners and permissions. However there are a few cases where `atomic_write` cannot change the file ownership or permissions, this error is caught and skipped over trusting in the user/filesystem to ensure the file is accessible to the processes that need it.

NOTE. Due to the chmod operation `atomic_write` performs, if the target file has an ACL set on it this ACL will be recalculated/modified.
3716

3717
WARNING. Note you can't append with `atomic_write`.
3718 3719 3720

The auxiliary file is written in a standard directory for temporary files, but you can pass a directory of your choice as second argument.

3721
NOTE: Defined in `active_support/core_ext/file/atomic.rb`.
3722

3723
Extensions to `Marshal`
X
Xavier Noria 已提交
3724
-----------------------
3725 3726 3727

### `load`

X
Xavier Noria 已提交
3728
Active Support adds constant autoloading support to `load`.
3729

3730
For example, the file cache store deserializes this way:
3731 3732 3733 3734 3735

```ruby
File.open(file_name) { |f| Marshal.load(f) }
```

3736
If the cached data refers to a constant that is unknown at that point, the autoloading mechanism is triggered and if it succeeds the deserialization is retried transparently.
3737

X
Xavier Noria 已提交
3738
WARNING. If the argument is an `IO` it needs to respond to `rewind` to be able to retry. Regular files respond to `rewind`.
3739 3740 3741

NOTE: Defined in `active_support/core_ext/marshal.rb`.

3742
Extensions to `Logger`
3743
----------------------
3744

3745
### `around_[level]`
3746

3747
Takes two arguments, a `before_message` and `after_message` and calls the current level method on the `Logger` instance, passing in the `before_message`, then the specified message, then the `after_message`:
3748

3749
```ruby
V
Vijay Dev 已提交
3750 3751
logger = Logger.new("log/development.log")
logger.around_info("before", "after") { |logger| logger.info("during") }
3752
```
3753

3754
### `silence`
3755 3756 3757

Silences every log level lesser to the specified one for the duration of the given block. Log level orders are: debug, info, error and fatal.

3758
```ruby
V
Vijay Dev 已提交
3759 3760 3761 3762 3763
logger = Logger.new("log/development.log")
logger.silence(Logger::INFO) do
  logger.debug("In space, no one can hear you scream.")
  logger.info("Scream all you want, small mailman!")
end
3764
```
3765

3766
### `datetime_format=`
3767

3768
Modifies the datetime format output by the formatter class associated with this logger. If the formatter class does not have a `datetime_format` method then this is ignored.
3769

3770
```ruby
V
Vijay Dev 已提交
3771 3772
class Logger::FormatWithTime < Logger::Formatter
  cattr_accessor(:datetime_format) { "%Y%m%d%H%m%S" }
V
Vijay Dev 已提交
3773

V
Vijay Dev 已提交
3774 3775
  def self.call(severity, timestamp, progname, msg)
    "#{timestamp.strftime(datetime_format)} -- #{String === msg ? msg : msg.inspect}\n"
3776
  end
V
Vijay Dev 已提交
3777
end
V
Vijay Dev 已提交
3778

V
Vijay Dev 已提交
3779 3780 3781
logger = Logger.new("log/development.log")
logger.formatter = Logger::FormatWithTime
logger.info("<- is the current time")
3782
```
3783

3784
NOTE: Defined in `active_support/core_ext/logger.rb`.
3785

3786
Extensions to `NameError`
3787
-------------------------
3788

3789
Active Support adds `missing_name?` to `NameError`, which tests whether the exception was raised because of the name passed as argument.
3790 3791 3792

The name may be given as a symbol or string. A symbol is tested against the bare constant name, a string is against the fully-qualified constant name.

3793
TIP: A symbol can represent a fully-qualified constant name as in `:"ActiveRecord::Base"`, so the behavior for symbols is defined for convenience, not because it has to be that way technically.
3794

3795
For example, when an action of `PostsController` is called Rails tries optimistically to use `PostsHelper`. It is OK that the helper module does not exist, so if an exception for that constant name is raised it should be silenced. But it could be the case that `posts_helper.rb` raises a `NameError` due to an actual unknown constant. That should be reraised. The method `missing_name?` provides a way to distinguish both cases:
3796

3797
```ruby
3798 3799 3800 3801 3802 3803 3804 3805 3806
def default_helper_module!
  module_name = name.sub(/Controller$/, '')
  module_path = module_name.underscore
  helper module_path
rescue MissingSourceFile => e
  raise e unless e.is_missing? "#{module_path}_helper"
rescue NameError => e
  raise e unless e.missing_name? "#{module_name}Helper"
end
3807
```
3808

3809
NOTE: Defined in `active_support/core_ext/name_error.rb`.
3810

3811
Extensions to `LoadError`
3812
-------------------------
3813

3814
Active Support adds `is_missing?` to `LoadError`, and also assigns that class to the constant `MissingSourceFile` for backwards compatibility.
3815

3816
Given a path name `is_missing?` tests whether the exception was raised due to that particular file (except perhaps for the ".rb" extension).
3817

3818
For example, when an action of `PostsController` is called Rails tries to load `posts_helper.rb`, but that file may not exist. That's fine, the helper module is not mandatory so Rails silences a load error. But it could be the case that the helper module does exist and in turn requires another library that is missing. In that case Rails must reraise the exception. The method `is_missing?` provides a way to distinguish both cases:
3819

3820
```ruby
3821 3822 3823 3824 3825
def default_helper_module!
  module_name = name.sub(/Controller$/, '')
  module_path = module_name.underscore
  helper module_path
rescue MissingSourceFile => e
3826
  raise e unless e.is_missing? "helpers/#{module_path}_helper"
3827 3828 3829
rescue NameError => e
  raise e unless e.missing_name? "#{module_name}Helper"
end
3830
```
3831

3832
NOTE: Defined in `active_support/core_ext/load_error.rb`.