Spec-Zone.ru › Ruby on Rails 4.2

класс Object::HashWithIndifferentAccess

Родитель:
Hash

Реализует хэш, где ключи :foo и "foo" считаются одинаковыми.

rgb = ActiveSupport::HashWithIndifferentAccess.new

rgb[:black] = '#000000'
rgb[:black]  # => '#000000'
rgb['black'] # => '#000000'

rgb['white'] = '#FFFFFF'
rgb[:white]  # => '#FFFFFF'
rgb['white'] # => '#FFFFFF'

Внутренне символы отображаются в строки при использовании в качестве ключей во всём интерфейсе (вызов []=, merge, и т.д.). Это отображение относится к публичному интерфейсу. Например, если:

hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1)

Вам гарантируется, что ключ будет возвращён как строка:

hash.keys # => ["a"]

Технически принимаются и другие типы ключей:

hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1)
hash[0] = 0
hash # => {"a"=>1, 0=>0}

но этот класс предназначен для случаев, когда ожидаются ключи в виде строк или символов, и удобно понимать оба как одно и то же. Например, хэш params в Ruby on Rails.

Обратите внимание, что расширения ядра определяют Hash#with_indifferent_access:

rgb = { black: '#000000', white: '#FFFFFF' }.with_indifferent_access

что может быть полезно.

Публичные Классовые Методы

[](*args) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 83
def self.[](*args)
  new.merge!(Hash[*args])
end
new(constructor = {}) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 58
def initialize(constructor = {})
  if constructor.respond_to?(:to_hash)
    super()
    update(constructor)
  else
    super(constructor)
  end
end
Вызывает метод суперкласса
new_from_hash_copying_default(hash) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 75
def self.new_from_hash_copying_default(hash)
  hash = hash.to_hash
  new(hash).tap do |new_hash|
    new_hash.default = hash.default
    new_hash.default_proc = hash.default_proc if hash.default_proc
  end
end

Общедоступные методы экземпляра

[]=(ключ, значение) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 96
def []=(key, value)
  regular_writer(convert_key(key), convert_value(value, for: :assignment))
end

Присваивает новое значение хешу:

hash = ActiveSupport::HashWithIndifferentAccess.new
hash[:key] = 'value'

Это значение можно позже получить, используя либо :key или +'ключ'+.

Также алиас: regular_writer, store
compact() Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 253
def compact
  dup.tap(&:compact!)
end
deep_stringify_keys() Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 233
def deep_stringify_keys; dup end
deep_stringify_keys!() Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 231
def deep_stringify_keys!; self end
deep_symbolize_keys() Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 237
def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
default(ключ = nil) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 67
def default(key = nil)
  if key.is_a?(Symbol) && include?(key = key.to_s)
    self[key]
  else
    super
  end
end
Вызов метода предка
delete(ключ) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 226
def delete(key)
  super(convert_key(key))
end

Удаляет указанный ключ из хеша.

Вызов метода предка
dup() Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 189
def dup
  self.class.new(self).tap do |new_hash|
    set_defaults(new_hash)
  end
end

Возвращает поверхностную копию хеша.

hash = ActiveSupport::HashWithIndifferentAccess.new({ a: { b: 'b' } })
dup  = hash.dup
dup[:a][:c] = 'c'

hash[:a][:c] # => nil
dup[:a][:c]  # => "c"
extractable_options?() Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 46
def extractable_options?
  true
end

Возвращает true, чтобы Array#extract_options! находил члены этого класса.

fetch(ключ, *дополнительные) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 167
def fetch(key, *extras)
  super(convert_key(key), *extras)
end

То же, что и Hash#fetch, где переданный в качестве аргумента ключ может быть строкой или символом:

counters = ActiveSupport::HashWithIndifferentAccess.new
counters[:foo] = 1

counters.fetch('foo')          # => 1
counters.fetch(:bar, 0)        # => 0
counters.fetch(:bar) { |key| 0 } # => 0
counters.fetch(:zoo)           # => KeyError: key not found: "zoo"
Вызов метода предка
has_key?(ключ)
Псевдоним для: key?
include?(ключ)
Псевдоним для: key?
key?(ключ) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 149
def key?(key)
  super(convert_key(key))
end

Проверяет хеш на наличие ключа, соответствующего переданному аргументу:

hash = ActiveSupport::HashWithIndifferentAccess.new
hash['key'] = 'value'
hash.key?(:key)  # => true
hash.key?('key') # => true
Вызов метода предка
Также алиас: include?, has_key?, member?
member?(ключ)
Псевдоним для: key?
merge(хеш, &блок) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 198
def merge(hash, &block)
  self.dup.update(hash, &block)
end

Этот метод имеет те же семантические значения, что и update, за исключением того, что он не изменяет получателя, а возвращает новый хеш с неопределенным доступом с результатом слияния.

merge!(другой_хеш)
Псевдоним для: update
nested_under_indifferent_access() Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 54
def nested_under_indifferent_access
  self
end
regular_update(другой_хеш)
Псевдоним для: update
regular_writer(ключ, значение)
Псевдоним для: []=
reject(*аргументы, &блок) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 244
def reject(*args, &block)
  dup.tap { |hash| hash.reject!(*args, &block) }
end
replace(другой_хеш) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 221
def replace(other_hash)
  super(self.class.new_from_hash_copying_default(other_hash))
end

Заменяет содержимое этого хеша на другой_хеш.

h = { "a" => 100, "b" => 200 }
h.replace({ "c" => 300, "d" => 400 }) # => {"c"=>300, "d"=>400}
Вызов метода предка
reverse_merge(другой_хеш) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 208
def reverse_merge(other_hash)
  super(self.class.new_from_hash_copying_default(other_hash))
end

Подобно merge, но наоборот: Объединяет получателя в аргумент и возвращает новый хеш с неопределенным доступом в качестве результата:

hash = ActiveSupport::HashWithIndifferentAccess.new
hash['a'] = nil
hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1}
Вызов метода предка Hash#reverse_merge
reverse_merge!(другой_хеш) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 213
def reverse_merge!(other_hash)
  replace(reverse_merge( other_hash ))
end

Такие же семантические значения, как и reverse_merge, но изменяет получателя на месте.

select(*аргументы, &блок) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 240
def select(*args, &block)
  dup.tap { |hash| hash.select!(*args, &block) }
end
store(ключ, значение)
Псевдоним для: []=
stringify_keys() Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 232
def stringify_keys; dup end
stringify_keys!() Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 230
def stringify_keys!; self end
symbolize_keys() Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 236
def symbolize_keys; to_hash.symbolize_keys! end
to_hash() Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 258
def to_hash
  _new_hash = Hash.new
  set_defaults(_new_hash)

  each do |key, value|
    _new_hash[key] = convert_value(value, for: :to_hash)
  end
  _new_hash
end

Преобразовать в обычный хеш со строковыми ключами.

to_options!() Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 238
def to_options!; self end
transform_values(*args, &block) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 248
def transform_values(*args, &block)
  return to_enum(:transform_values) unless block_given?
  dup.tap { |hash| hash.transform_values!(*args, &block) }
end
update(other_hash) { |convert_key(key), self, value| ... } Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 127
def update(other_hash)
  if other_hash.is_a? HashWithIndifferentAccess
    super(other_hash)
  else
    other_hash.to_hash.each_pair do |key, value|
      if block_given? && key?(key)
        value = yield(convert_key(key), self[key], value)
      end
      regular_writer(convert_key(key), convert_value(value))
    end
    self
  end
end

Обновляет получателя на месте, объединяя переданный в качестве аргумента хеш:

hash_1 = ActiveSupport::HashWithIndifferentAccess.new
hash_1[:key] = 'value'

hash_2 = ActiveSupport::HashWithIndifferentAccess.new
hash_2[:key] = 'New Value!'

hash_1.update(hash_2) # => {"key"=>"New Value!"}

Аргумент может быть как ActiveSupport::HashWithIndifferentAccess, так и обычным Hash. В обоих случаях объединение учитывает семантику доступа без различия типов ключей.

Если аргумент — это обычный хеш с ключами :key, и +“ключ”+, то только одно из значений попадет в получатель, но какое именно — не определено.

Если задан блок, значение для дублирующихся ключей будет определяться результатом вызова блока с дублирующимся ключом, значением в получателе и значением в other_hash. Правила для дублирующихся ключей следуют семантике доступа без различия типов ключей:

hash_1[:key] = 10
hash_2['key'] = 12
hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
Вызывает метод суперкласса
Также алиасировано как: regular_update, merge!
values_at(*indices) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 177
def values_at(*indices)
  indices.collect { |key| self[convert_key(key)] }
end

Возвращает массив значений по указанным индексам:

hash = ActiveSupport::HashWithIndifferentAccess.new
hash[:a] = 'x'
hash[:b] = 'y'
hash.values_at('a', 'b') # => ["x", "y"]
with_indifferent_access() Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 50
def with_indifferent_access
  dup
end

Защищенные методы экземпляра

convert_key(key) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 269
def convert_key(key)
  key.kind_of?(Symbol) ? key.to_s : key
end
convert_value(value, options = {}) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 273
def convert_value(value, options = {})
  if value.is_a? Hash
    if options[:for] == :to_hash
      value.to_hash
    else
      value.nested_under_indifferent_access
    end
  elsif value.is_a?(Array)
    if options[:for] != :assignment || value.frozen?
      value = value.dup
    end
    value.map! { |e| convert_value(e, options) }
  else
    value
  end
end
set_defaults(target) Показать исходный код
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 290
def set_defaults(target)
  if default_proc
    target.default_proc = default_proc.dup
  else
    target.default = default
  end
end

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

Spec-Zone.ru

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