Class: Object

Inherits:
BasicObject
Defined in:
activesupport/lib/active_support/core_ext/object/duplicable.rb,
activesupport/lib/active_support/json/encoding.rb,
activesupport/lib/active_support/core_ext/object/try.rb,
activesupport/lib/active_support/core_ext/object/blank.rb,
activesupport/lib/active_support/core_ext/object/to_param.rb,
activesupport/lib/active_support/core_ext/object/to_query.rb,
activesupport/lib/active_support/core_ext/object/acts_like.rb,
activesupport/lib/active_support/core_ext/kernel/agnostics.rb,
activesupport/lib/active_support/core_ext/object/returning.rb,
activesupport/lib/active_support/core_ext/object/with_options.rb,
activesupport/lib/active_support/core_ext/string/output_safety.rb,
activesupport/lib/active_support/core_ext/object/instance_variables.rb

Overview

Most objects are cloneable, but not all. For example you can't dup nil:

nil.dup # => TypeError: can't dup NilClass

Classes may signal their instances are not duplicable removing dup/clone or raising exceptions from them. So, to dup an arbitrary object you normally use an optimistic approach and are ready to catch an exception, say:

arbitrary_object.dup rescue object

Rails dups objects in a few critical spots where they are not that arbitrary. That rescue is very expensive (like 40 times slower than a predicate), and it is often triggered.

That's why we hardcode the following cases and check duplicable? instead of using that rescue idiom.

Instance Method Summary (collapse)

Instance Method Details

- (Object) `(command)

Makes backticks behave (somewhat more) similarly on all platforms. On win32 `nonexistent_command` raises Errno::ENOENT; on Unix, the spawned shell prints a message to stderr and sets $?. We emulate Unix on the former but not the latter.



6
7
8
9
10
# File 'activesupport/lib/active_support/core_ext/kernel/agnostics.rb', line 6

def `(command) #:nodoc:
  super
rescue Errno::ENOENT => e
  STDERR.puts "#$0: #{e}"
end

- (Boolean) acts_like?(duck)

A duck-type assistant method. For example, Active Support extends Date to define an acts_like_date? method, and extends Time to define acts_like_time?. As a result, we can do “x.acts_like?(:time)” and “x.acts_like?(:date)” to do duck-type-safe comparisons, since classes that we want to act like Time simply need to define an acts_like_time? method.

Returns:

  • (Boolean)


7
8
9
# File 'activesupport/lib/active_support/core_ext/object/acts_like.rb', line 7

def acts_like?(duck)
  respond_to? :acts_like_#{duck}?"
end

- (Object) as_json(options = nil)

:nodoc:



130
131
132
133
134
135
136
# File 'activesupport/lib/active_support/json/encoding.rb', line 130

def as_json(options = nil) #:nodoc:
  if respond_to?(:to_hash)
    to_hash
  else
    instance_values
  end
end

- (Boolean) blank?

An object is blank if it's false, empty, or a whitespace string. For example, “”, “ ”, nil, [], and {} are blank.

This simplifies:

if !address.nil? && !address.empty?

…to:

if !address.blank?

Returns:

  • (Boolean)


12
13
14
# File 'activesupport/lib/active_support/core_ext/object/blank.rb', line 12

def blank?
  respond_to?(:empty?) ? empty? : !self
end

- (Object) copy_instance_variables_from(object, exclude = [])

Copies the instance variables of object into self.

Instance variable names in the exclude array are ignored. If object responds to protected_instance_variables the ones returned are also ignored. For example, Rails controllers implement that method.

In both cases strings and symbols are understood, and they have to include the at sign.

class C
  def initialize(x, y, z)
    @x, @y, @z = x, y, z
  end

  def protected_instance_variables
    %w(@z)
  end
end

a = C.new(0, 1, 2)
b = C.new(3, 4, 5)

a.copy_instance_variables_from(b, [:@y])
# a is now: @x = 3, @y = 1, @z = 2


61
62
63
64
65
66
# File 'activesupport/lib/active_support/core_ext/object/instance_variables.rb', line 61

def copy_instance_variables_from(object, exclude = []) #:nodoc:
  exclude += object.protected_instance_variables if object.respond_to? :protected_instance_variables

  vars = object.instance_variables.map(&:to_s) - exclude.map(&:to_s)
  vars.each { |name| instance_variable_set(name, object.instance_variable_get(name)) }
end

- (Boolean) duplicable?

Can you safely .dup this object? False for nil, false, true, symbols, numbers, class and module objects; true otherwise.

Returns:

  • (Boolean)


20
21
22
# File 'activesupport/lib/active_support/core_ext/object/duplicable.rb', line 20

def duplicable?
  true
end

- (Boolean) html_safe?

Returns:

  • (Boolean)


55
56
57
# File 'activesupport/lib/active_support/core_ext/string/output_safety.rb', line 55

def html_safe?
  false
end

- (Object) instance_values

Returns a hash that maps instance variable names without “@” to their corresponding values. Keys are strings both in Ruby 1.8 and 1.9.

class C
  def initialize(x, y)
    @x, @y = x, y
  end
end

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


12
13
14
15
16
17
# File 'activesupport/lib/active_support/core_ext/object/instance_variables.rb', line 12

def instance_values #:nodoc:
  instance_variables.inject({}) do |values, name|
    values[name.to_s[1..-1]] = instance_variable_get(name)
    values
  end
end

- (Object) presence

Returns object if it's #present? otherwise returns nil. object.presence is equivalent to object.present? ? object : nil.

This is handy for any representation of objects where blank is the same as not present at all. For example, this simplifies a common check for HTTP POST/query parameters:

state   = params[:state]   if params[:state].present?
country = params[:country] if params[:country].present?
region  = state || country || 'US'

…becomes:

region = params[:state].presence || params[:country].presence || 'US'


35
36
37
# File 'activesupport/lib/active_support/core_ext/object/blank.rb', line 35

def presence
  self if present?
end

- (Boolean) present?

An object is present if it's not blank.

Returns:

  • (Boolean)


17
18
19
# File 'activesupport/lib/active_support/core_ext/object/blank.rb', line 17

def present?
  !blank?
end

- (Object) returning(value) {|value| ... }

Returns value after yielding value to the block. This simplifies the process of constructing an object, performing work on the object, and then returning the object from a method. It is a Ruby-ized realization of the K combinator, courtesy of Mikael Brockman.

Examples

# Without returning
def foo
  values = []
  values << "bar"
  values << "baz"
  return values
end

foo # => ['bar', 'baz']

# returning with a local variable
def foo
  returning values = [] do
    values << 'bar'
    values << 'baz'
  end
end

foo # => ['bar', 'baz']

# returning with a block argument
def foo
  returning [] do |values|
    values << 'bar'
    values << 'baz'
  end
end

foo # => ['bar', 'baz']

Yields:

  • (value)


38
39
40
41
42
# File 'activesupport/lib/active_support/core_ext/object/returning.rb', line 38

def returning(value)
  ActiveSupport::Deprecation.warn('Object#returning has been deprecated in favor of Object#tap.', caller)
  yield(value)
  value
end

- (Object) to_param

Alias of to_s.



5
6
7
# File 'activesupport/lib/active_support/core_ext/object/to_param.rb', line 5

def to_param
  to_s
end

- (Object) to_query(key)

Converts an object into a string suitable for use as a URL query string, using the given key as the param name.

Note: This method is defined as a default implementation for all Objects for Hash#to_query to work.



8
9
10
11
# File 'activesupport/lib/active_support/core_ext/object/to_query.rb', line 8

def to_query(key)
  require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
  "#{CGI.escape(key.to_s).gsub(/%(5B|5D)/n) { [$1].pack('H*') }}=#{CGI.escape(to_param.to_s)}"
end

- (Object) with_options(options) {|ActiveSupport::OptionMerger.new(self, options)| ... }

An elegant way to factor duplication out of options passed to a series of method calls. Each method called in the block, with the block variable as the receiver, will have its options merged with the default options hash provided. Each method called on the block variable must take an options hash as its final argument.

with_options :order => 'created_at', :class_name => 'Comment' do |post|
  post.has_many :comments, :conditions => ['approved = ?', true], :dependent => :delete_all
  post.has_many :unapproved_comments, :conditions => ['approved = ?', false]
  post.has_many :all_comments
end

Can also be used with an explicit receiver:

map.with_options :controller => "people" do |people|
  people.connect "/people",     :action => "index"
  people.connect "/people/:id", :action => "show"
end

Yields:



23
24
25
# File 'activesupport/lib/active_support/core_ext/object/with_options.rb', line 23

def with_options(options)
  yield ActiveSupport::OptionMerger.new(self, options)
end