Spec-Zone.ru › Ruby on Rails 7.2

класс Object

Родитель:
BasicObject
Включенные модули:
ActiveSupport::NumericWithFormat

Константы

APP_PATH

Открытые методы экземпляров

acts_like?(duck) Показать исходный код
# File activesupport/lib/active_support/core_ext/object/acts_like.rb, line 33
def acts_like?(duck)
  case duck
  when :time
    respond_to? :acts_like_time?
  when :date
    respond_to? :acts_like_date?
  when :string
    respond_to? :acts_like_string?
  else
    respond_to? :"acts_like_#{duck}?"
  end
end

Предоставляет способ проверки, действует ли какой-либо класс как другой класс на основе наличия метода с соответствующим именем.

Класс, предоставляющий тот же интерфейс, что и SomeClass, может определить маркерный метод, названный acts_like_some_class?, чтобы сигнализировать о своей совместимости вызывающим сторонам acts_like?(:some_class).

Например, Active Support расширяет Date для определения метода acts_like_date?, и расширяет Time для определения acts_like_time?. В результате разработчики могут вызвать x.acts_like?(:time) и x.acts_like?(:date) для проверки совместимости по типу «утка», и классы, способные действовать как Time, также могут определить метод acts_like_time? для взаимодействия.

Обратите внимание, что маркерный метод ожидается только для существования. Он не вызывается, поэтому его тело или возвращаемое значение не имеют значения.

Пример: Класс, предоставляющий интерфейс, аналогичный String

Этот класс может определить:

class Stringish
  def acts_like_string?
  end
end

Затем код клиента может запросить безопасность типа «утка» таким образом:

Stringish.new.acts_like?(:string) # => true
blank?() Показать исходный код
# File activesupport/lib/active_support/core_ext/object/blank.rb, line 18
def blank?
  respond_to?(:empty?) ? !!empty? : false
end

Объект считается пустым, если он ложный, пустой или строка из пробельных символов. Например, nil, ”, ‘ ’, [], {}, и false являются пустыми.

Это упрощает

!address || address.empty?

до

address.blank?

@return [true, false]

deep_dup() Показать исходный код
# File activesupport/lib/active_support/core_ext/object/deep_dup.rb, line 15
def deep_dup
  duplicable? ? dup : self
end

Возвращает глубокую копию объекта, если он дублируемый. Если он не дублируемый, возвращает self.

object = Object.new
dup    = object.deep_dup
dup.instance_variable_set(:@a, 1)

object.instance_variable_defined?(:@a) # => false
dup.instance_variable_defined?(:@a)    # => true
duplicable?() Показать исходный код
# File activesupport/lib/active_support/core_ext/object/duplicable.rb, line 26
def duplicable?
  true
end

Можно ли безопасно продублировать этот объект?

Ложь для объектов методов; истина в противном случае.

html_safe?() Показать исходный код
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 7
def html_safe?
  false
end
in?(another_object) Показать исходный код
# File activesupport/lib/active_support/core_ext/object/inclusion.rb, line 15
def in?(another_object)
  case another_object
  when Range
    another_object.cover?(self)
  else
    another_object.include?(self)
  end
rescue NoMethodError
  raise ArgumentError.new("The parameter passed to #in? must respond to #include?")
end

Возвращает true, если этот объект входит в аргумент.

Когда аргумент является Range, используется #cover? для правильной обработки проверки включения в открытых интервалах. В противном случае аргумент должен быть любым объектом, который отвечает на #include?. Использование:

characters = ["Konata", "Kagami", "Tsukasa"]
"Konata".in?(characters) # => true

Для аргументов, не являющихся Range, это вызовет ArgumentError, если аргумент не отвечает на #include?.

instance_values() Показать исходный код
# File activesupport/lib/active_support/core_ext/object/instance_variables.rb, line 14
def instance_values
  instance_variables.to_h do |ivar|
    [ivar[1..-1].freeze, instance_variable_get(ivar)]
  end
end

Возвращает хеш со строковыми ключами, которые сопоставляют имена переменных экземпляра без «@» с соответствующими значениями.

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

C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
instance_variable_names() Показать исходный код
# File activesupport/lib/active_support/core_ext/object/instance_variables.rb, line 29
def instance_variable_names
  instance_variables.map(&:name)
end

Возвращает массив имён переменных экземпляра как строки, включая «@».

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

C.new(0, 1).instance_variable_names # => ["@y", "@x"]
presence() Показать исходный код
# File activesupport/lib/active_support/core_ext/object/blank.rb, line 45
def presence
  self if present?
end

Возвращает получателя, если он присутствует, в противном случае возвращает nil. object.presence эквивалентно

object.present? ? object : nil

Например, что-то вроде

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

становится

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

@return [Object]

presence_in(another_object) Показать исходный код
# File activesupport/lib/active_support/core_ext/object/inclusion.rb, line 34
def presence_in(another_object)
  in?(another_object) ? self : nil
end

Возвращает получателя, если он входит в аргумент, в противном случае возвращает nil. Аргумент должен быть любым объектом, который отвечает на #include?. Использование:

params[:bucket_type].presence_in %w( project calendar )

Это вызовет ArgumentError, если аргумент не отвечает на #include?.

@return [Object]

present?() Показать исходный код
# File activesupport/lib/active_support/core_ext/object/blank.rb, line 25
def present?
  !blank?
end

Объект присутствует, если он не пустой.

@return [true, false]

to_param() Показать исходный код
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 7
def to_param
  to_s
end

Псевдоним to_s.

to_query(key) Показать исходный код
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 13
def to_query(key)
  "#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
end

Преобразует объект в строку, подходящую для использования в строке запроса URL, используя указанное key в качестве имени параметра.

try(*args, &block) Показать исходный код
# File activesupport/lib/active_support/core_ext/object/try.rb, line 39
  

Вызывает общедоступный метод, имя которого передаётся в качестве первого аргумента, точно так же, как и public_send, за исключением того, что если получатель не отвечает на него, вызов возвращает nil, а не вызывает исключение.

Этот метод определен для возможности записи

@person.try(:name)

вместо

@person.name if @person

try вызовы могут быть объединены:

@person.try(:spouse).try(:name)

вместо

@person.spouse.name if @person && @person.spouse

try также вернёт nil, если получатель не отвечает на метод:

@person.try(:non_existing_method) # => nil

вместо

@person.non_existing_method if @person.respond_to?(:non_existing_method) # => nil

try вернёт nil при вызове на nil независимо от того, отвечает ли он на метод:

nil.try(:to_i) # => nil, rather than 0

Аргументы и блоки передаются методу, если вызываются:

@posts.try(:each_slice, 2) do |a, b|
  ...
end

Количество аргументов в сигнатуре должно совпадать. Если объект отвечает на метод, вызов выполняется, и ArgumentError всё ещё возникает в случае несоответствия аргументов.

Если try вызывается без аргументов, он передаёт получателя блоку, если он не nil.

@person.try do |p|
  ...
end

Вы также можете вызвать try с блоком без приёма аргумента, и блок будет вычисляться в instance_eval:

@person.try { upcase.truncate(50) }

Обратите также внимание, что try определён в Object. Поэтому он не будет работать с экземплярами классов, у которых Object нет среди предков, таких как прямые подклассы BasicObject.

try!(*args, &block) Показать исходный код
# File activesupport/lib/active_support/core_ext/object/try.rb, line 104

То же, что и try, но вызывает исключение NoMethodError если получатель не nil и не реализует вызываемый метод.

"a".try!(:upcase) # => "A"
nil.try!(:upcase) # => nil
123.try!(:upcase) # => NoMethodError: undefined method `upcase' for 123:Integer
END_OF_DOCUMENT_MARKER
with(**attributes) { |self| ... } Показать исходный код
# File activesupport/lib/active_support/core_ext/object/with.rb, line 26
def with(**attributes)
  old_values = {}
  begin
    attributes.each do |key, value|
      old_values[key] = public_send(key)
      public_send("#{key}=", value)
    end
    yield self
  ensure
    old_values.each do |key, old_value|
      public_send("#{key}=", old_value)
    end
  end
end

Устанавливает и восстанавливает публичные атрибуты внутри блока.

client.timeout # => 5
client.with(timeout: 1) do |c|
  c.timeout # => 1
end
client.timeout # => 5

Получатель передаётся в предоставленный блок.

Этот метод — сокращение для распространённого шаблона begin/ensure:

old_value = object.attribute
begin
  object.attribute = new_value
  # do things
ensure
  object.attribute = old_value
end

Его можно использовать с любым объектом, если методы чтения и записи являются публичными.

with_options(options, &block) Показать исходный код
# File activesupport/lib/active_support/core_ext/object/with_options.rb, line 92
def with_options(options, &block)
  option_merger = ActiveSupport::OptionMerger.new(self, options)

  if block
    block.arity.zero? ? option_merger.instance_eval(&block) : block.call(option_merger)
  else
    option_merger
  end
end

Элегантный способ избежать дублирования опций, передаваемых в серию вызовов методов. Каждый вызов метода в блоке, с переменной блока в качестве получателя, будет иметь свои опции, слитые со значениями по умолчанию options Hash или похожим объектом, который предоставляется. Каждый вызов метода для переменной блока должен принимать хэш опций в качестве последнего аргумента.

Без with_options, этот код содержит дублирование:

class Account < ActiveRecord::Base
  has_many :customers, dependent: :destroy
  has_many :products,  dependent: :destroy
  has_many :invoices,  dependent: :destroy
  has_many :expenses,  dependent: :destroy
end

Используя with_options, мы можем убрать дублирование:

class Account < ActiveRecord::Base
  with_options dependent: :destroy do |assoc|
    assoc.has_many :customers
    assoc.has_many :products
    assoc.has_many :invoices
    assoc.has_many :expenses
  end
end

Его также можно использовать с явным получателем:

I18n.with_options locale: user.locale, scope: 'newsletter' do |i18n|
  subject i18n.t :subject
  body    i18n.t :body, user_name: user.name
end

Если вы не передаёте явного получателя, весь блок выполняется в контексте слияния опций:

class Account < ActiveRecord::Base
  with_options dependent: :destroy do
    has_many :customers
    has_many :products
    has_many :invoices
    has_many :expenses
  end
end

with_options также может быть вложен, так как вызов перенаправляется на его получатель.

ПРИМЕЧАНИЕ: Каждый уровень вложенности будет сливать унаследованные значения по умолчанию в дополнение к своим собственным.

class Post < ActiveRecord::Base
  with_options if: :persisted?, length: { minimum: 50 } do
    validates :content, if: -> { content.present? }
  end
end

Код эквивалентен:

validates :content, length: { minimum: 50 }, if: -> { content.present? }

Поэтому унаследованное значение по умолчанию для ключа if игнорируется.

ПРИМЕЧАНИЕ: Нельзя неявно вызывать методы класса внутри with_options. Можно получить доступ к этим методам, используя имя класса:

class Phone < ActiveRecord::Base
  enum :phone_number_type, { home: 0, office: 1, mobile: 2 }

  with_options presence: true do
    validates :phone_number_type, inclusion: { in: Phone.phone_number_types.keys }
  end
end

Если аргумент блока отсутствует, возвращается декорированный Object экземпляр:

module MyStyledHelpers
  def styled
    with_options style: "color: red;"
  end
end

styled.link_to "I'm red", "/"
# => <a href="/" style="color: red;">I'm red</a>

styled.button_tag "I'm red too!"
# => <button style="color: red;">I'm red too!</button>

© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API