Spec-Zone.ru › Ruby 3.2

класс Hash

Родитель:
Объект
Включенные модули:
Enumerable

В хеше каждому уникальному ключу соответствует определенное значение.

Хеш имеет определенное сходство с массивом, но:

  • Индекс массива всегда является целым числом.

  • Ключ хеша может быть (почти) любым объектом.

Синтаксис данных хеша

Старый синтаксис данных хеша использует «стрелку хеша», =>:

h = {:foo => 0, :bar => 1, :baz => 2}
h # => {:foo=>0, :bar=>1, :baz=>2}

В качестве альтернативы, но только для ключа хеша, являющегося символом, можно использовать новый синтаксис в стиле JSON, где каждое слово без кавычек становится символом:

h = {foo: 0, bar: 1, baz: 2}
h # => {:foo=>0, :bar=>1, :baz=>2}

Вы также можете использовать строку вместо слова без кавычек:

h = {'foo': 0, 'bar': 1, 'baz': 2}
h # => {:foo=>0, :bar=>1, :baz=>2}

И вы можете смешивать стили:

h = {foo: 0, :bar => 1, 'baz': 2}
h # => {:foo=>0, :bar=>1, :baz=>2}

Но попытка использовать синтаксис в стиле JSON для ключа, который не является словом без кавычек или строкой, является ошибкой:

# Raises SyntaxError (syntax error, unexpected ':', expecting =>):
h = {0: 'zero'}

Hash значение может быть опущено, что означает, что значение будет взято из контекста по имени ключа:

x = 0
y = 100
h = {x:, y:}
h # => {:x=>0, :y=>100}

Общие применения

Вы можете использовать хеш для присвоения имен объектам:

person = {name: 'Matz', language: 'Ruby'}
person # => {:name=>"Matz", :language=>"Ruby"}

Вы можете использовать хеш для присвоения имен аргументам методов:

def some_method(hash)
  p hash
end
some_method({foo: 0, bar: 1, baz: 2}) # => {:foo=>0, :bar=>1, :baz=>2}

Примечание: когда последним аргументом вызова метода является хеш, фигурные скобки можно опустить:

some_method(foo: 0, bar: 1, baz: 2) # => {:foo=>0, :bar=>1, :baz=>2}

Вы можете использовать хеш для инициализации объекта:

class Dev
  attr_accessor :name, :language
  def initialize(hash)
    self.name = hash[:name]
    self.language = hash[:language]
  end
end
matz = Dev.new(name: 'Matz', language: 'Ruby')
matz # => #<Dev: @name="Matz", @language="Ruby">

Создание хеша

Вы можете явно создать объект хеша с помощью:

  • литерала хеша.

Вы можете преобразовать определенные объекты в хеши с помощью:

  • Метода Hash.

Вы можете создать хеш, вызвав метод Hash.new.

Создать пустой хеш:

h = Hash.new
h # => {}
h.class # => Hash

Вы можете создать хеш, вызвав метод Hash.[].

Создать пустой хеш:

h = Hash[]
h # => {}

Создать хеш с начальными записями:

h = Hash[foo: 0, bar: 1, baz: 2]
h # => {:foo=>0, :bar=>1, :baz=>2}

Вы можете создать хеш, используя его литеральную форму (фигурные скобки).

Создать пустой хеш:

h = {}
h # => {}

Создать хеш с начальными записями:

h = {foo: 0, bar: 1, baz: 2}
h # => {:foo=>0, :bar=>1, :baz=>2}

Основы значений хеша

Самый простой способ извлечения значения хеша (метод экземпляра []):

h = {foo: 0, bar: 1, baz: 2}
h[:foo] # => 0

Самый простой способ создания или обновления значения хеша (метод экземпляра []=):

h = {foo: 0, bar: 1, baz: 2}
h[:bat] = 3 # => 3
h # => {:foo=>0, :bar=>1, :baz=>2, :bat=>3}
h[:foo] = 4 # => 4
h # => {:foo=>4, :bar=>1, :baz=>2, :bat=>3}

Самый простой способ удаления записи хеша (метод экземпляра delete):

h = {foo: 0, bar: 1, baz: 2}
h.delete(:bar) # => 1
h # => {:foo=>0, :baz=>2}

Порядок записей

Объект хеша представляет свои записи в порядке их создания. Это видно в:

  • Итерационных методах, таких как each, each_key, each_pair, each_value.

  • Других методах, чувствительных к порядку, таких как shift, keys, values.

  • Строке, возвращаемой методом inspect.

Новый хеш имеет начальный порядок в соответствии с заданными записями:

h = Hash[foo: 0, bar: 1]
h # => {:foo=>0, :bar=>1}

Новые записи добавляются в конец:

h[:baz] = 2
h # => {:foo=>0, :bar=>1, :baz=>2}

Обновление значения не влияет на порядок:

h[:baz] = 3
h # => {:foo=>0, :bar=>1, :baz=>3}

Но создание вновь удаленной записи может повлиять на порядок:

h.delete(:foo)
h[:foo] = 5
h # => {:bar=>1, :baz=>3, :foo=>5}

Ключи хеша

Равенство ключей хеша

Два объекта рассматриваются как один и тот же ключ хеша, когда их hash значение идентично, и два объекта eql? друг другу.

Изменение активного ключа хеша

Изменение ключа хеша во время его использования повреждает индекс хеша.

У этого хеша ключи — массивы:

a0 = [ :foo, :bar ]
a1 = [ :baz, :bat ]
h = {a0 => 0, a1 => 1}
h.include?(a0) # => true
h[a0] # => 0
a0.hash # => 110002110

Изменение элемента массива a0[0] изменяет его значение хеша:

a0[0] = :bam
a0.hash # => 1069447059

И повреждает индекс хеша:

h.include?(a0) # => false
h[a0] # => nil

Вы можете восстановить индекс хеша, используя метод rehash:

h.rehash # => {[:bam, :bar]=>0, [:baz, :bat]=>1}
h.include?(a0) # => true
h[a0] # => 0

Строковый ключ всегда безопасен. Это потому, что непромороженный строковый ключ, переданный в качестве ключа, будет заменён дублированной и замороженной строкой:

s = 'foo'
s.frozen? # => false
h = {s => 0}
first_key = h.keys.first
first_key.frozen? # => true

Ключи хеша, определённые пользователем

Чтобы использовать объекты в качестве ключей хеша, объекты должны реализовывать методы hash и eql?. Примечание: это требование не применяется, если хеш использует compare_by_identity, так как сравнение в этом случае будет основано на идентификаторе объекта ключа, а не на hash и eql?.

Объект определяет базовую реализацию для hash и eq? , что делает каждый объект уникальным ключом. Обычно пользовательские классы захотят переопределить эти методы, чтобы обеспечить осмысленное поведение, или, например, унаследовать от структуры, которая имеет полезные определения для них.

Типичная реализация hash основана на данных объекта, а eql? обычно является псевдонимом переопределённого метода ==:

class Book
  attr_reader :author, :title

  def initialize(author, title)
    @author = author
    @title = title
  end

  def ==(other)
    self.class === other &&
      other.author == @author &&
      other.title == @title
  end

  alias eql? ==

  def hash
    @author.hash ^ @title.hash # XOR
  end
end

book1 = Book.new 'matz', 'Ruby in a Nutshell'
book2 = Book.new 'matz', 'Ruby in a Nutshell'

reviews = {}

reviews[book1] = 'Great reference!'
reviews[book2] = 'Nice and compact!'

reviews.length #=> 1

Значения по умолчанию

Методы [], values_at и dig должны возвращать значение, связанное с определённым ключом. Когда этот ключ не найден, это значение определяется его проком по умолчанию (если он есть) или значением по умолчанию (изначально ‘nil`).

Вы можете получить значение по умолчанию с помощью метода default:

h = Hash.new
h.default # => nil

Вы можете задать значение по умолчанию, передав аргумент методу Hash.new или с помощью метода default=

h = Hash.new(-1)
h.default # => -1
h.default = 0
h.default # => 0

Это значение по умолчанию возвращается для [], values_at и dig при отсутствии ключа:

counts = {foo: 42}
counts.default # => nil (default)
counts[:foo] = 42
counts[:bar] # => nil
counts.default = 0
counts[:bar] # => 0
counts.values_at(:foo, :bar, :baz) # => [42, 0, 0]
counts.dig(:bar) # => 0

Обратите внимание, что значение по умолчанию используется без дублирования. Не рекомендуется задавать значение по умолчанию для изменяемого объекта:

synonyms = Hash.new([])
synonyms[:hello] # => []
synonyms[:hello] << :hi # => [:hi], but this mutates the default!
synonyms.default # => [:hi]
synonyms[:world] << :universe
synonyms[:world] # => [:hi, :universe], oops
synonyms.keys # => [], oops

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

Прок по умолчанию

Когда для хеша установлен прок по умолчанию (т.е., не nil), значение по умолчанию, возвращаемое методом [], определяется только проком по умолчанию.

Вы можете получить прок по умолчанию с помощью метода default_proc:

h = Hash.new
h.default_proc # => nil

Вы можете установить прок по умолчанию, вызвав Hash.new с блоком или вызвав метод default_proc=

h = Hash.new { |hash, key| "Default value for #{key}" }
h.default_proc.class # => Proc
h.default_proc = proc { |hash, key| "Default value for #{key.inspect}" }
h.default_proc.class # => Proc

Когда прок по умолчанию установлен (т.е., не nil) и вызывается метод [] с несуществующим ключом, [] вызывает прок по умолчанию с объектом хеша и отсутствующим ключом, а затем возвращает значение, возвращаемое проком:

h = Hash.new { |hash, key| "Default value for #{key}" }
h[:nosuch] # => "Default value for nosuch"

Обратите внимание, что в приведённом выше примере запись для ключа :nosuch не создаётся:

h.include?(:nosuch) # => false

Однако, сам прок может добавить новую запись:

synonyms = Hash.new { |hash, key| hash[key] = [] }
synonyms.include?(:hello) # => false
synonyms[:hello] << :hi # => [:hi]
synonyms[:world] << :universe # => [:universe]
synonyms.keys # => [:hello, :world]

Обратите внимание, что установка прока по умолчанию очистит значение по умолчанию, и наоборот.

Здесь есть

Сначала, что есть где-то ещё. Класс Hash:

  • Унаследован от класса Object.

  • Включает модуль Enumerable, который предоставляет десятки дополнительных методов.

Здесь класс Hash предоставляет методы, которые полезны для:

  • Создание хеша

  • Установка состояния хеша

  • Запросы

  • Сравнение

  • Получение

  • Присвоение

  • Удаление

  • Итерация

  • Преобразование

  • Преобразование ключей и значений

  • И многое другое…

Класс Hash также включает методы из модуля Enumerable.

Методы для создания хеша

  • ::[]: Возвращает новый хеш, заполненный заданными объектами.

  • ::new: Возвращает новый пустой хеш.

  • ::try_convert: Возвращает новый хеш, созданный из заданного объекта.

Методы для установки состояния хеша

  • compare_by_identity: Устанавливает self для сравнения ключей только по идентичности.

  • default=: Устанавливает значение по умолчанию.

  • default_proc=: Устанавливает прок по умолчанию.

  • rehash: Перестраивает таблицу хеша, пересчитывая индекс хеша для каждого ключа.

Методы для запросов

END_OF_DOCUMENT_MARKER
  • any?: Возвращает значение, указывающее, удовлетворяет ли какой-либо элемент заданному критерию.

  • compare_by_identity?: Возвращает значение, указывающее, рассматривает ли хеш только идентичность при сравнении ключей.

  • default: Возвращает значение по умолчанию или значение по умолчанию для заданного ключа.

  • default_proc: Возвращает процедуру по умолчанию.

  • empty?: Возвращает значение, указывающее, нет ли записей.

  • eql?: Возвращает значение, указывающее, равен ли данный объект self.

  • hash: Возвращает целое числовой код хеша.

  • has_value?: Возвращает значение, указывающее, является ли данный объект значением в self.

  • include?, has_key?, member?, key?: Возвращает значение, указывающее, является ли данный объект ключом в self.

  • length, size: Возвращает количество записей.

  • value?: Возвращает значение, указывающее, является ли данный объект значением в self.

Методы для сравнения

  • <: Возвращает значение, указывающее, является ли self надмножеством данного объекта.

  • <=: Возвращает значение, указывающее, является ли self подмножеством данного объекта.

  • ==: Возвращает значение, указывающее, равен ли данный объект self.

  • >: Возвращает значение, указывающее, является ли self надмножеством данного объекта.

  • >=: Возвращает значение, указывающее, является ли self надмножеством данного объекта.

Методы для извлечения

  • []: Возвращает значение, связанное с заданным ключом.

  • assoc: Возвращает массив из 2 элементов, содержащий заданный ключ и его значение.

  • dig: Возвращает объект вложенных объектов, указанный заданным ключом и дополнительными аргументами.

  • fetch: Возвращает значение для заданного ключа.

  • fetch_values: Возвращает массив, содержащий значения, связанные с заданными ключами.

  • key: Возвращает ключ для первой найденной записи со значением.

  • keys: Возвращает массив, содержащий все ключи в self.

  • rassoc: Возвращает массив из 2 элементов, содержащий ключ и значение первой найденной записи, имеющей заданное значение.

  • values: Возвращает массив, содержащий все значения в self.

  • values_at: Возвращает массив, содержащий значения для заданных ключей.

Методы для присваивания

  • []=, store: Связывает заданный ключ со значением.

  • merge: Возвращает хеш, образованный слиянием каждого данного хеша в копию self.

  • merge!, update: Объединяет каждый заданный хеш в self.

  • replace: Заменяет всё содержимое self содержимым данного хеша.

Методы для удаления

Эти методы удаляют записи из self:

  • clear: Удаляет все записи из self.

  • compact!: Удаляет все записи со значением nil из self.

  • delete: Удаляет запись для заданного ключа.

  • delete_if: Удаляет записи, выбранные заданным блоком.

  • filter!, select!: Сохраняет только те записи, которые выбраны заданным блоком.

  • keep_if: Сохраняет только те записи, которые выбраны заданным блоком.

  • reject!: Удаляет записи, выбранные заданным блоком.

  • shift: Удаляет и возвращает первую запись.

Эти методы возвращают копию self с удалёнными записями:

  • compact: Возвращает копию self с удалёнными всеми записями со значением nil.

  • except: Возвращает копию self с удалёнными записями для указанных ключей.

  • filter, select: Возвращает копию self только с теми записями, которые выбраны заданным блоком.

  • reject: Возвращает копию self с удалёнными записями, как указано в заданном блоке.

  • slice: Возвращает хеш, содержащий записи для заданных ключей.

Методы для итерации

  • each, each_pair: Вызывает заданный блок для каждой пары ключ-значение.

  • each_key: Вызывает заданный блок для каждого ключа.

  • each_value: Вызывает заданный блок для каждого значения.

Методы для преобразования

  • inspect, to_s: Возвращает новую String, содержащую записи хеша.

  • to_a: Возвращает новый массив из массивов по 2 элемента; каждый вложенный массив содержит пару ключ-значение из self.

  • to_h: Возвращает self если это хеш; если это подкласс хеша, возвращает хеш, содержащий записи из self.

  • to_hash: Возвращает self.

  • to_proc: Возвращает процедуру, которая сопоставляет заданный ключ его значению.

Методы для преобразования ключей и значений

  • transform_keys: Возвращает копию self с изменёнными ключами.

  • transform_keys!: Изменяет ключи в self.

  • transform_values: Возвращает копию self с изменёнными значениями.

  • transform_values!: Изменяет значения в self.

Другие методы

  • flatten: Возвращает массив, который является 1-мерным разглаживанием self.

  • invert: Возвращает хеш с инвертированной каждой парой ключ-значение.

Методы публичного класса

Hash[] → new_empty_hash Показать исходный код
Hash[hash] → new_hash
Hash[ [*2_element_arrays] ] → new_hash
Hash[*objects] → new_hash
static VALUE
rb_hash_s_create(int argc, VALUE *argv, VALUE klass)
{
    VALUE hash, tmp;

    if (argc == 1) {
        tmp = rb_hash_s_try_convert(Qnil, argv[0]);
        if (!NIL_P(tmp)) {
            hash = hash_alloc(klass);
            hash_copy(hash, tmp);
            return hash;
        }

        tmp = rb_check_array_type(argv[0]);
        if (!NIL_P(tmp)) {
            long i;

            hash = hash_alloc(klass);
            for (i = 0; i < RARRAY_LEN(tmp); ++i) {
                VALUE e = RARRAY_AREF(tmp, i);
                VALUE v = rb_check_array_type(e);
                VALUE key, val = Qnil;

                if (NIL_P(v)) {
                    rb_raise(rb_eArgError, "wrong element type %s at %ld (expected array)",
                             rb_builtin_class_name(e), i);
                }
                switch (RARRAY_LEN(v)) {
                  default:
                    rb_raise(rb_eArgError, "invalid number of elements (%ld for 1..2)",
                             RARRAY_LEN(v));
                  case 2:
                    val = RARRAY_AREF(v, 1);
                  case 1:
                    key = RARRAY_AREF(v, 0);
                    rb_hash_aset(hash, key, val);
                }
            }
            return hash;
        }
    }
    if (argc % 2 != 0) {
        rb_raise(rb_eArgError, "odd number of arguments for Hash");
    }

    hash = hash_alloc(klass);
    rb_hash_bulk_insert(argc, argv, hash);
    hash_verify(hash);
    return hash;
}

Возвращает новый объект Hash, заполненный заданными объектами, если таковые имеются. См. Hash::new.

Без аргументов возвращает новый пустой Hash.

Если единственным аргументом является Hash, возвращает новый Hash, заполненный записями из заданного Hash, исключая значение по умолчанию или proc.

h = {foo: 0, bar: 1, baz: 2}
Hash[h] # => {:foo=>0, :bar=>1, :baz=>2}

Если единственным аргументом является массив из 2-элементных массивов, возвращает новый объект Hash, где каждый 2-элементный массив формирует пару ключ-значение:

Hash[ [ [:foo, 0], [:bar, 1] ] ] # => {:foo=>0, :bar=>1}

Если количество аргументов чётное, возвращает новый объект Hash, где каждая пара последовательных аргументов становится парой ключ-значение:

Hash[:foo, 0, :bar, 1] # => {:foo=>0, :bar=>1}

Возникает исключение, если список аргументов не соответствует ни одному из вышеперечисленных форматов.

new(default_value = nil) → new_hash Показать исходный код
new {|hash, key| ... } → new_hash
static VALUE
rb_hash_initialize(int argc, VALUE *argv, VALUE hash)
{
    VALUE ifnone;

    rb_hash_modify(hash);
    if (rb_block_given_p()) {
        rb_check_arity(argc, 0, 0);
        ifnone = rb_block_proc();
        SET_PROC_DEFAULT(hash, ifnone);
    }
    else {
        rb_check_arity(argc, 0, 1);
        ifnone = argc == 0 ? Qnil : argv[0];
        RHASH_SET_IFNONE(hash, ifnone);
    }

    return hash;
}

Возвращает новый пустой объект Hash.

Начальное значение по умолчанию и начальный proc для нового hash зависят от используемой формы. См. Значения по умолчанию.

Если не указан ни аргумент, ни блок, то значение по умолчанию и proc устанавливаются в nil:

h = Hash.new
h.default # => nil
h.default_proc # => nil

Если указан аргумент default_value , но не указан блок, то значение по умолчанию устанавливается в указанный default_value, а proc — в nil:

h = Hash.new(false)
h.default # => false
h.default_proc # => nil

Если указан блок, но не указан аргумент, то блок устанавливается как proc по умолчанию, а значение по умолчанию устанавливается в nil:

h = Hash.new {|hash, key| "Default value for #{key}" }
h.default # => nil
h.default_proc.class # => Proc
h[:nosuch] # => "Default value for nosuch"
ruby2_keywords_hash(hash) → hash Показать исходный код
static VALUE
rb_hash_s_ruby2_keywords_hash(VALUE dummy, VALUE hash)
{
    Check_Type(hash, T_HASH);
    hash = rb_hash_dup(hash);
    RHASH(hash)->basic.flags |= RHASH_PASS_AS_KEYWORDS;
    return hash;
}

Создаёт копию заданного hash и добавляет флаг ruby2_keywords. Этот метод не предназначен для повседневного использования; используется для отладки, исследования и в некоторых действительно необходимых случаях, например, для десериализации аргументов.

h = {k: 1}
h = Hash.ruby2_keywords_hash(h)
def foo(k: 42)
  k
end
foo(*[h]) #=> 1 with neither a warning or an error
ruby2_keywords_hash?(hash) → true or false Показать исходный код
static VALUE
rb_hash_s_ruby2_keywords_hash_p(VALUE dummy, VALUE hash)
{
    Check_Type(hash, T_HASH);
    return RBOOL(RHASH(hash)->basic.flags & RHASH_PASS_AS_KEYWORDS);
}

Проверяет, помечен ли заданный hash флагом Module#ruby2_keywords (или Proc#ruby2_keywords). Этот метод не предназначен для повседневного использования; используется для отладки, исследования и в некоторых действительно необходимых случаях, например, для сериализации аргументов.

ruby2_keywords def foo(*args)
  Hash.ruby2_keywords_hash?(args.last)
end
foo(k: 1)   #=> true
foo({k: 1}) #=> false
try_convert(obj) → obj, new_hash, or nil Показать исходный код
static VALUE
rb_hash_s_try_convert(VALUE dummy, VALUE hash)
{
    return rb_check_hash_type(hash);
}

Если obj является объектом Hash, возвращает obj.

В противном случае, если obj отвечает методу :to_hash, вызывает obj.to_hash и возвращает результат.

Возвращает nil если obj не отвечает методу :to_hash

Возникает исключение, если obj.to_hash не возвращает объект Hash.

Публичные методы экземпляров

hash < other_hash → true или false Показать исходный код
static VALUE
rb_hash_lt(VALUE hash, VALUE other)
{
    other = to_hash(other);
    if (RHASH_SIZE(hash) >= RHASH_SIZE(other)) return Qfalse;
    return hash_le(hash, other);
}

Возвращает true, если hash является собственным подмножеством other_hash, в противном случае — false:

h1 = {foo: 0, bar: 1}
h2 = {foo: 0, bar: 1, baz: 2}
h1 < h2 # => true
h2 < h1 # => false
h1 < h1 # => false
hash <= other_hash → true или false Показать исходный код
static VALUE
rb_hash_le(VALUE hash, VALUE other)
{
    other = to_hash(other);
    if (RHASH_SIZE(hash) > RHASH_SIZE(other)) return Qfalse;
    return hash_le(hash, other);
}

Возвращает true, если hash является подмножеством other_hash, в противном случае — false:

h1 = {foo: 0, bar: 1}
h2 = {foo: 0, bar: 1, baz: 2}
h1 <= h2 # => true
h2 <= h1 # => false
h1 <= h1 # => true
hash == object → true или false Показать исходный код
static VALUE
rb_hash_equal(VALUE hash1, VALUE hash2)
{
    return hash_equal(hash1, hash2, FALSE);
}

Возвращает true, если все перечисленные ниже условия выполняются:

  • object является объектом Hash.

  • hash и object имеют одинаковые ключи (независимо от порядка).

  • Для каждого ключа key, hash[key] == object[key].

В противном случае возвращает false.

Равны:

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {foo: 0, bar: 1, baz: 2}
h1 == h2 # => true
h3 = {baz: 2, bar: 1, foo: 0}
h1 == h3 # => true
hash > other_hash → true или false Показать исходный код
static VALUE
rb_hash_gt(VALUE hash, VALUE other)
{
    other = to_hash(other);
    if (RHASH_SIZE(hash) <= RHASH_SIZE(other)) return Qfalse;
    return hash_le(other, hash);
}

Возвращает true, если hash является собственным надмножеством other_hash, в противном случае — false:

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {foo: 0, bar: 1}
h1 > h2 # => true
h2 > h1 # => false
h1 > h1 # => false
hash >= other_hash → true или false Показать исходный код
static VALUE
rb_hash_ge(VALUE hash, VALUE other)
{
    other = to_hash(other);
    if (RHASH_SIZE(hash) < RHASH_SIZE(other)) return Qfalse;
    return hash_le(other, hash);
}

Возвращает true, если hash является надмножеством other_hash, в противном случае — false:

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {foo: 0, bar: 1}
h1 >= h2 # => true
h2 >= h1 # => false
h1 >= h1 # => true
hash[key] → value Показать исходный код
VALUE
rb_hash_aref(VALUE hash, VALUE key)
{
    st_data_t val;

    if (hash_stlike_lookup(hash, key, &val)) {
        return (VALUE)val;
    }
    else {
        return rb_hash_default_value(hash, key);
    }
}

Возвращает значение, соответствующее заданному key, если оно найдено:

h = {foo: 0, bar: 1, baz: 2}
h[:foo] # => 0

Если key не найдено, возвращает значение по умолчанию (см. Значения по умолчанию):

h = {foo: 0, bar: 1, baz: 2}
h[:nosuch] # => nil
hash[key] = value → value Показать исходный код
VALUE
rb_hash_aset(VALUE hash, VALUE key, VALUE val)
{
    int iter_lev = RHASH_ITER_LEV(hash);

    rb_hash_modify(hash);

    if (RHASH_TABLE_NULL_P(hash)) {
        if (iter_lev > 0) no_new_key();
        ar_alloc_table(hash);
    }

    if (RHASH_TYPE(hash) == &identhash || rb_obj_class(key) != rb_cString) {
        RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset, val);
    }
    else {
        RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset_str, val);
    }
    return val;
}

Hash#store — псевдоним для Hash#[]=.

Связывает заданное value с заданным key; возвращает value.

Если заданный key существует, заменяет его значение на заданное value; порядок не затрагивается (см. Порядок элементов):

h = {foo: 0, bar: 1}
h[:foo] = 2 # => 2
h.store(:bar, 3) # => 3
h # => {:foo=>2, :bar=>3}

Если заданный key не существует, добавляет key и value; новая запись находится последней в порядке (см. Порядок элементов):

h = {foo: 0, bar: 1}
h[:baz] = 2 # => 2
h.store(:bat, 3) # => 3
h # => {:foo=>0, :bar=>1, :baz=>2, :bat=>3}
Также алиас: store
any? → true или false Показать исходный код
any?(object) → true или false
any? {|key, value| ... } → true или false
static VALUE
rb_hash_any_p(int argc, VALUE *argv, VALUE hash)
{
    VALUE args[2];
    args[0] = Qfalse;

    rb_check_arity(argc, 0, 1);
    if (RHASH_EMPTY_P(hash)) return Qfalse;
    if (argc) {
        if (rb_block_given_p()) {
            rb_warn("given block not used");
        }
        args[1] = argv[0];

        rb_hash_foreach(hash, any_p_i_pattern, (VALUE)args);
    }
    else {
        if (!rb_block_given_p()) {
            /* yields pairs, never false */
            return Qtrue;
        }
        if (rb_block_pair_yield_optimizable())
            rb_hash_foreach(hash, any_p_i_fast, (VALUE)args);
        else
            rb_hash_foreach(hash, any_p_i, (VALUE)args);
    }
    return args[0];
}

Возвращает true, если хотя бы один элемент удовлетворяет заданному критерию; в противном случае — false.

Без аргумента и без блока возвращает true, если self непусто, и false, если пусто.

С аргументом object и без блока возвращает true, если для любого ключа key выполняется h.assoc(key) == object; в противном случае — false:

h = {foo: 0, bar: 1, baz: 2}
h.any?([:bar, 1]) # => true
h.any?([:bar, 0]) # => false
h.any?([:baz, 1]) # => false

Без аргумента и с блоком вызываем блок для каждой пары ключ-значение; возвращает true, если блок возвращает любое истинное значение, и false в противном случае:

h = {foo: 0, bar: 1, baz: 2}
h.any? {|key, value| value < 3 } # => true
h.any? {|key, value| value > 3 } # => false
assoc(key) → new_array или nil Показать исходный код
static VALUE
rb_hash_assoc(VALUE hash, VALUE key)
{
    st_table *table;
    const struct st_hash_type *orighash;
    VALUE args[2];

    if (RHASH_EMPTY_P(hash)) return Qnil;

    ar_force_convert_table(hash, __FILE__, __LINE__);
    HASH_ASSERT(RHASH_ST_TABLE_P(hash));
    table = RHASH_ST_TABLE(hash);
    orighash = table->type;

    if (orighash != &identhash) {
        VALUE value;
        struct reset_hash_type_arg ensure_arg;
        struct st_hash_type assochash;

        assochash.compare = assoc_cmp;
        assochash.hash = orighash->hash;
        table->type = &assochash;
        args[0] = hash;
        args[1] = key;
        ensure_arg.hash = hash;
        ensure_arg.orighash = orighash;
        value = rb_ensure(lookup2_call, (VALUE)&args, reset_hash_type, (VALUE)&ensure_arg);
        if (!UNDEF_P(value)) return rb_assoc_new(key, value);
    }

    args[0] = key;
    args[1] = Qnil;
    rb_hash_foreach(hash, assoc_i, (VALUE)args);
    return args[1];
}

Если заданный key найден, возвращает массив из двух элементов, содержащий этот ключ и его значение:

h = {foo: 0, bar: 1, baz: 2}
h.assoc(:bar) # => [:bar, 1]

Возвращает nil, если ключ key не найден.

clear → self Показать исходный код
VALUE
rb_hash_clear(VALUE hash)
{
    rb_hash_modify_check(hash);

    if (RHASH_ITER_LEV(hash) > 0) {
        rb_hash_foreach(hash, clear_i, 0);
    }
    else if (RHASH_AR_TABLE_P(hash)) {
        ar_clear(hash);
    }
    else {
        st_clear(RHASH_ST_TABLE(hash));
    }

    return hash;
}

Удаляет все записи хеша; возвращает self.

compact → new_hash Показать исходный код
static VALUE
rb_hash_compact(VALUE hash)
{
    VALUE result = rb_hash_new();
    if (!RHASH_EMPTY_P(hash)) {
        rb_hash_foreach(hash, set_if_not_nil, result);
    }
    return result;
}

Возвращает копию self со всеми значениями nil, удаленными:

h = {foo: 0, bar: nil, baz: 2, bat: nil}
h1 = h.compact
h1 # => {:foo=>0, :baz=>2}
compact! → self или nil Показать исходный код
static VALUE
rb_hash_compact_bang(VALUE hash)
{
    st_index_t n;
    rb_hash_modify_check(hash);
    n = RHASH_SIZE(hash);
    if (n) {
        rb_hash_foreach(hash, delete_if_nil, hash);
        if (n != RHASH_SIZE(hash))
            return hash;
    }
    return Qnil;
}

Возвращает self со всеми значениями nil, удаленными (на месте):

h = {foo: 0, bar: nil, baz: 2, bat: nil}
h.compact! # => {:foo=>0, :baz=>2}

Возвращает nil, если никакие записи не были удалены.

compare_by_identity → self Показать исходный код
VALUE
rb_hash_compare_by_id(VALUE hash)
{
    VALUE tmp;
    st_table *identtable;

    if (rb_hash_compare_by_id_p(hash)) return hash;

    rb_hash_modify_check(hash);
    ar_force_convert_table(hash, __FILE__, __LINE__);
    HASH_ASSERT(RHASH_ST_TABLE_P(hash));

    tmp = hash_alloc(0);
    identtable = rb_init_identtable_with_size(RHASH_SIZE(hash));
    RHASH_ST_TABLE_SET(tmp, identtable);
    rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
    st_free_table(RHASH_ST_TABLE(hash));
    RHASH_ST_TABLE_SET(hash, identtable);
    RHASH_ST_CLEAR(tmp);

    return hash;
}

Устанавливает self учитывать только тождество при сравнении ключей; два ключа считаются одинаковыми только если они являются одним и тем же объектом; возвращает self.

По умолчанию эти два объекта считаются одинаковыми ключами, поэтому s1 перезапишет s0:

s0 = 'x'
s1 = 'x'
h = {}
h.compare_by_identity? # => false
h[s0] = 0
h[s1] = 1
h # => {"x"=>1}

После вызова #compare_by_identity ключи считаются различными и, следовательно, не перезаписывают друг друга:

h = {}
h.compare_by_identity # => {}
h.compare_by_identity? # => true
h[s0] = 0
h[s1] = 1
h # => {"x"=>0, "x"=>1}
compare_by_identity? → true или false Показать исходный код
MJIT_FUNC_EXPORTED VALUE
rb_hash_compare_by_id_p(VALUE hash)
{
    return RBOOL(RHASH_ST_TABLE_P(hash) && RHASH_ST_TABLE(hash)->type == &identhash);
}

Возвращает true, если compare_by_identity был вызван, и false в противном случае.

deconstruct_keys(p1) Показать исходный код
static VALUE
rb_hash_deconstruct_keys(VALUE hash, VALUE keys)
{
    return hash;
}
default → object Показать исходный код
default(key) → object
static VALUE
rb_hash_default(int argc, VALUE *argv, VALUE hash)
{
    VALUE ifnone;

    rb_check_arity(argc, 0, 1);
    ifnone = RHASH_IFNONE(hash);
    if (FL_TEST(hash, RHASH_PROC_DEFAULT)) {
        if (argc == 0) return Qnil;
        return call_default_proc(ifnone, hash, argv[0]);
    }
    return ifnone;
}

Возвращает значение по умолчанию для данного key. Возвращаемое значение определяется либо проком по умолчанию, либо значением по умолчанию. См. Значения по умолчанию.

Без аргумента, возвращает текущее значение по умолчанию:

h = {}
h.default # => nil

Если key указано, возвращает значение по умолчанию для key, независимо от того, существует ли этот ключ:

h = Hash.new { |hash, key| hash[key] = "No key #{key}"}
h[:foo] = "Hello"
h.default(:foo) # => "No key foo"
default = value → object Показать исходный код
static VALUE
rb_hash_set_default(VALUE hash, VALUE ifnone)
{
    rb_hash_modify_check(hash);
    SET_DEFAULT(hash, ifnone);
    return ifnone;
}

Устанавливает значение по умолчанию на value; возвращает value:

h = {}
h.default # => nil
h.default = false # => false
h.default # => false

См. Значения по умолчанию.

default_proc → proc or nil Показать исходный код
static VALUE
rb_hash_default_proc(VALUE hash)
{
    if (FL_TEST(hash, RHASH_PROC_DEFAULT)) {
        return RHASH_IFNONE(hash);
    }
    return Qnil;
}

Возвращает проброшенную по умолчанию для self (см. Значения по умолчанию):

h = {}
h.default_proc # => nil
h.default_proc = proc {|hash, key| "Default value for #{key}" }
h.default_proc.class # => Proc
default_proc = proc → proc Показать исходный код
VALUE
rb_hash_set_default_proc(VALUE hash, VALUE proc)
{
    VALUE b;

    rb_hash_modify_check(hash);
    if (NIL_P(proc)) {
        SET_DEFAULT(hash, proc);
        return proc;
    }
    b = rb_check_convert_type_with_id(proc, T_DATA, "Proc", idTo_proc);
    if (NIL_P(b) || !rb_obj_is_proc(b)) {
        rb_raise(rb_eTypeError,
                 "wrong default_proc type %s (expected Proc)",
                 rb_obj_classname(proc));
    }
    proc = b;
    SET_PROC_DEFAULT(hash, proc);
    return proc;
}

Устанавливает по умолчанию для self в proc: (см. Значения по умолчанию):

h = {}
h.default_proc # => nil
h.default_proc = proc { |hash, key| "Default value for #{key}" }
h.default_proc.class # => Proc
h.default_proc = nil
h.default_proc # => nil
delete(key) → value or nil Показать исходный код
delete(key) {|key| ... } → object
static VALUE
rb_hash_delete_m(VALUE hash, VALUE key)
{
    VALUE val;

    rb_hash_modify_check(hash);
    val = rb_hash_delete_entry(hash, key);

    if (!UNDEF_P(val)) {
        return val;
    }
    else {
        if (rb_block_given_p()) {
            return rb_yield(key);
        }
        else {
            return Qnil;
        }
    }
}

Удаляет запись для заданного key и возвращает связанное с ним значение.

Если блок не задан и key найден, удаляет запись и возвращает связанное с ней значение:

h = {foo: 0, bar: 1, baz: 2}
h.delete(:bar) # => 1
h # => {:foo=>0, :baz=>2}

Если блок не задан и key не найден, возвращает nil.

Если задан блок и key найден, игнорирует блок, удаляет запись и возвращает связанное с ней значение:

h = {foo: 0, bar: 1, baz: 2}
h.delete(:baz) { |key| raise 'Will never happen'} # => 2
h # => {:foo=>0, :bar=>1}

Если задан блок и key не найден, вызывает блок и возвращает значение, возвращенное блоком:

h = {foo: 0, bar: 1, baz: 2}
h.delete(:nosuch) { |key| "Key #{key} not found" } # => "Key nosuch not found"
h # => {:foo=>0, :bar=>1, :baz=>2}
delete_if {|key, value| ... } → self Показать исходный код
delete_if → new_enumerator
VALUE
rb_hash_delete_if(VALUE hash)
{
    RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    rb_hash_modify_check(hash);
    if (!RHASH_TABLE_EMPTY_P(hash)) {
        rb_hash_foreach(hash, delete_if_i, hash);
    }
    return hash;
}

Если задан блок, вызывает блок с каждой парой «ключ-значение»; удаляет каждую запись, для которой блок возвращает истинное значение; возвращает self:

h = {foo: 0, bar: 1, baz: 2}
h.delete_if {|key, value| value > 0 } # => {:foo=>0}

Если блок не задан, возвращает новый перечислитель:

h = {foo: 0, bar: 1, baz: 2}
e = h.delete_if # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:delete_if>
e.each { |key, value| value > 0 } # => {:foo=>0}
dig(key, *identifiers) → object Показать исходный код
static VALUE
rb_hash_dig(int argc, VALUE *argv, VALUE self)
{
    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
    self = rb_hash_aref(self, *argv);
    if (!--argc) return self;
    ++argv;
    return rb_obj_dig(argc, argv, self, Qnil);
}

Находит и возвращает объект вложенных объектов, который задается key и identifiers. Вложенные объекты могут быть экземплярами различных классов. См. Методы Dig.

Вложенные Hash:

h = {foo: {bar: {baz: 2}}}
h.dig(:foo) # => {:bar=>{:baz=>2}}
h.dig(:foo, :bar) # => {:baz=>2}
h.dig(:foo, :bar, :baz) # => 2
h.dig(:foo, :bar, :BAZ) # => nil

Вложенные Hash и массивы:

h = {foo: {bar: [:a, :b, :c]}}
h.dig(:foo, :bar, 2) # => :c

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

h = {foo: {bar: [:a, :b, :c]}}
h.dig(:hello) # => nil
h.default_proc = -> (hash, _key) { hash }
h.dig(:hello, :world) # => h
h.dig(:hello, :world, :foo, :bar, 2) # => :c
each {|key, value| ... } → self
each → new_enumerator

Hash#each является псевдонимом для Hash#each_pair.

Вызывает заданный блок с каждой парой «ключ-значение»; возвращает self:

h = {foo: 0, bar: 1, baz: 2}
h.each_pair {|key, value| puts "#{key}: #{value}"} # => {:foo=>0, :bar=>1, :baz=>2}

Вывод:

foo: 0
bar: 1
baz: 2

Возвращает новый перечислитель, если блок не задан:

h = {foo: 0, bar: 1, baz: 2}
e = h.each_pair # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:each_pair>
h1 = e.each {|key, value| puts "#{key}: #{value}"}
h1 # => {:foo=>0, :bar=>1, :baz=>2}

Вывод:

foo: 0
bar: 1
baz: 2
Псевдоним для: each_pair
each_key {|key| ... } → self Показать исходный код
each_key → new_enumerator
static VALUE
rb_hash_each_key(VALUE hash)
{
    RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    rb_hash_foreach(hash, each_key_i, 0);
    return hash;
}

Вызывает заданный блок с каждым ключом; возвращает self:

h = {foo: 0, bar: 1, baz: 2}
h.each_key {|key| puts key }  # => {:foo=>0, :bar=>1, :baz=>2}

Вывод:

foo
bar
baz

Возвращает новый перечислитель, если блок не задан:

h = {foo: 0, bar: 1, baz: 2}
e = h.each_key # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:each_key>
h1 = e.each {|key| puts key }
h1 # => {:foo=>0, :bar=>1, :baz=>2}

Вывод:

foo
bar
baz
each_pair {|key, value| ... } → self Показать исходный код
each_pair → new_enumerator
static VALUE
rb_hash_each_pair(VALUE hash)
{
    RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    if (rb_block_pair_yield_optimizable())
        rb_hash_foreach(hash, each_pair_i_fast, 0);
    else
        rb_hash_foreach(hash, each_pair_i, 0);
    return hash;
}

Hash#each является псевдонимом для Hash#each_pair.

Вызывает заданный блок с каждой парой «ключ-значение»; возвращает self:

h = {foo: 0, bar: 1, baz: 2}
h.each_pair {|key, value| puts "#{key}: #{value}"} # => {:foo=>0, :bar=>1, :baz=>2}

Вывод:

foo: 0
bar: 1
baz: 2

Возвращает новый перечислитель, если блок не задан:

h = {foo: 0, bar: 1, baz: 2}
e = h.each_pair # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:each_pair>
h1 = e.each {|key, value| puts "#{key}: #{value}"}
h1 # => {:foo=>0, :bar=>1, :baz=>2}

Вывод:

foo: 0
bar: 1
baz: 2
Также используется как псевдоним: each
each_value {|value| ... } → self Показать исходный код
each_value → new_enumerator
static VALUE
rb_hash_each_value(VALUE hash)
{
    RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    rb_hash_foreach(hash, each_value_i, 0);
    return hash;
}

Вызывает заданный блок с каждым значением; возвращает self:

h = {foo: 0, bar: 1, baz: 2}
h.each_value {|value| puts value } # => {:foo=>0, :bar=>1, :baz=>2}

Вывод:

0
1
2

Возвращает новый перечислитель, если блок не задан:

h = {foo: 0, bar: 1, baz: 2}
e = h.each_value # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:each_value>
h1 = e.each {|value| puts value }
h1 # => {:foo=>0, :bar=>1, :baz=>2}

Вывод:

0
1
2
empty? → true or false Показать исходный код
static VALUE
rb_hash_empty_p(VALUE hash)
{
    return RBOOL(RHASH_EMPTY_P(hash));
}

Возвращает true если нет записей в хеше, false в противном случае:

{}.empty? # => true
{foo: 0, bar: 1, baz: 2}.empty? # => false
eql? object → true or false Показать исходный код
static VALUE
rb_hash_eql(VALUE hash1, VALUE hash2)
{
    return hash_equal(hash1, hash2, TRUE);
}

Возвращает true если все из следующего верно:

  • object является объектом Hash.

  • hash и object имеют одинаковые ключи (независимо от порядка).

  • Для каждого ключа key, h[key] eql? object[key].

В противном случае возвращает false.

Равны:

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {foo: 0, bar: 1, baz: 2}
h1.eql? h2 # => true
h3 = {baz: 2, bar: 1, foo: 0}
h1.eql? h3 # => true
except(*keys) → a_hash Показать исходный код
static VALUE
rb_hash_except(int argc, VALUE *argv, VALUE hash)
{
    int i;
    VALUE key, result;

    result = hash_dup_with_compare_by_id(hash);

    for (i = 0; i < argc; i++) {
        key = argv[i];
        rb_hash_delete(result, key);
    }

    return result;
}

Возвращает новый Hash, исключая записи для заданных keys:

h = { a: 100, b: 200, c: 300 }
h.except(:a)          #=> {:b=>200, :c=>300}

Любые заданные keys которые не найдены, игнорируются.

fetch(key) → object Показать исходный код
fetch(key, default_value) → object
fetch(key) {|key| ... } → object
static VALUE
rb_hash_fetch_m(int argc, VALUE *argv, VALUE hash)
{
    VALUE key;
    st_data_t val;
    long block_given;

    rb_check_arity(argc, 1, 2);
    key = argv[0];

    block_given = rb_block_given_p();
    if (block_given && argc == 2) {
        rb_warn("block supersedes default value argument");
    }

    if (hash_stlike_lookup(hash, key, &val)) {
        return (VALUE)val;
    }
    else {
        if (block_given) {
            return rb_yield(key);
        }
        else if (argc == 1) {
            VALUE desc = rb_protect(rb_inspect, key, 0);
            if (NIL_P(desc)) {
                desc = rb_any_to_s(key);
            }
            desc = rb_str_ellipsize(desc, 65);
            rb_key_err_raise(rb_sprintf("key not found: %"PRIsVALUE, desc), hash, key);
        }
        else {
            return argv[1];
        }
    }
}

Возвращает значение для заданного key, если найден.

h = {foo: 0, bar: 1, baz: 2}
h.fetch(:bar) # => 1

Если key не найден и блок не задан, возвращает default_value:

{}.fetch(:nosuch, :default) # => :default

Если key не найден и задан блок, передает key блоку и возвращает значение, возвращенное блоком:

{}.fetch(:nosuch) {|key| "No key #{key}"} # => "No key nosuch"

Вызывает исключение KeyError если ни default_value ни блок не заданы.

Обратите внимание, что этот метод не использует значения ни default ни default_proc.

fetch_values(*keys) → new_array Показать исходный код
fetch_values(*keys) {|key| ... } → new_array
static VALUE
rb_hash_fetch_values(int argc, VALUE *argv, VALUE hash)
{
    VALUE result = rb_ary_new2(argc);
    long i;

    for (i=0; i<argc; i++) {
        rb_ary_push(result, rb_hash_fetch(hash, argv[i]));
    }
    return result;
}

Возвращает новый массив, содержащий значения, связанные с заданными ключами *keys:

h = {foo: 0, bar: 1, baz: 2}
h.fetch_values(:baz, :foo) # => [2, 0]

Возвращает новый пустой массив, если аргументов нет.

Когда задан блок, вызывает блок с каждым отсутствующим ключом, рассматривая значение, возвращенное блоком, как значение для этого ключа:

h = {foo: 0, bar: 1, baz: 2}
values = h.fetch_values(:bar, :foo, :bad, :bam) {|key| key.to_s}
values # => [1, 0, "bad", "bam"]

Когда блок не задан, вызывает исключение, если какой-либо заданный ключ не найден.

END_OF_DOCUMENT_MARKER
filter()

Hash#filter является псевдонимом для Hash#select.

Возвращает новый объект Hash, содержащий записи, для которых блок возвращает истинное значение:

h = {foo: 0, bar: 1, baz: 2}
h.select {|key, value| value < 2 } # => {:foo=>0, :bar=>1}

Возвращает новый Enumerator, если блок не указан:

h = {foo: 0, bar: 1, baz: 2}
e = h.select # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:select>
e.each {|key, value| value < 2 } # => {:foo=>0, :bar=>1}
Псевдоним для: select
filter!()

Hash#filter! является псевдонимом для Hash#select!.

Возвращает self, содержащий записи, для которых блок возвращает истинное значение:

h = {foo: 0, bar: 1, baz: 2}
h.select! {|key, value| value < 2 }  => {:foo=>0, :bar=>1}

Возвращает nil, если записи не были удалены.

Возвращает новый Enumerator, если блок не указан:

h = {foo: 0, bar: 1, baz: 2}
e = h.select!  # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:select!>
e.each { |key, value| value < 2 } # => {:foo=>0, :bar=>1}
Псевдоним для: select!
flatten → new_array Показать исходный код
flatten(level) → new_array
static VALUE
rb_hash_flatten(int argc, VALUE *argv, VALUE hash)
{
    VALUE ary;

    rb_check_arity(argc, 0, 1);

    if (argc) {
        int level = NUM2INT(argv[0]);

        if (level == 0) return rb_hash_to_a(hash);

        ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2);
        rb_hash_foreach(hash, flatten_i, ary);
        level--;

        if (level > 0) {
            VALUE ary_flatten_level = INT2FIX(level);
            rb_funcallv(ary, id_flatten_bang, 1, &ary_flatten_level);
        }
        else if (level < 0) {
            /* flatten recursively */
            rb_funcallv(ary, id_flatten_bang, 0, 0);
        }
    }
    else {
        ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2);
        rb_hash_foreach(hash, flatten_i, ary);
    }

    return ary;
}

Возвращает новый объект Array, являющийся 1-мерным разложением self.

По умолчанию вложенные массивы не разлагаются:

h = {foo: 0, bar: [:bat, 3], baz: 2}
h.flatten # => [:foo, 0, :bar, [:bat, 3], :baz, 2]

Принимает глубину рекурсивного разложения из целочисленного аргумента level:

h = {foo: 0, bar: [:bat, [:baz, [:bat, ]]]}
h.flatten(1) # => [:foo, 0, :bar, [:bat, [:baz, [:bat]]]]
h.flatten(2) # => [:foo, 0, :bar, :bat, [:baz, [:bat]]]
h.flatten(3) # => [:foo, 0, :bar, :bat, :baz, [:bat]]
h.flatten(4) # => [:foo, 0, :bar, :bat, :baz, :bat]

Когда level отрицательное, разлагает все вложенные массивы:

h = {foo: 0, bar: [:bat, [:baz, [:bat, ]]]}
h.flatten(-1) # => [:foo, 0, :bar, :bat, :baz, :bat]
h.flatten(-2) # => [:foo, 0, :bar, :bat, :baz, :bat]

Когда level равно нулю, возвращает эквивалент to_a:

h = {foo: 0, bar: [:bat, 3], baz: 2}
h.flatten(0) # => [[:foo, 0], [:bar, [:bat, 3]], [:baz, 2]]
h.flatten(0) == h.to_a # => true
has_key?(key) → true or false

Методы has_key?, key? и member? являются псевдонимами для #include?.

Возвращает true если key является ключом в self, в противном случае false.

Псевдоним для: include?
has_value?(value) → true or false Показать исходный код
static VALUE
rb_hash_has_value(VALUE hash, VALUE val)
{
    VALUE data[2];

    data[0] = Qfalse;
    data[1] = val;
    rb_hash_foreach(hash, rb_hash_search_value, (VALUE)data);
    return data[0];
}

Method value? является псевдонимом для #has_value?.

Возвращает true если value является значением в self, в противном случае false.

Также алиас: value?
hash → an_integer Показать исходный код
static VALUE
rb_hash_hash(VALUE hash)
{
    st_index_t size = RHASH_SIZE(hash);
    st_index_t hval = rb_hash_start(size);
    hval = rb_hash_uint(hval, (st_index_t)rb_hash_hash);
    if (size) {
        rb_hash_foreach(hash, hash_i, (VALUE)&hval);
    }
    hval = rb_hash_end(hval);
    return ST2FIX(hval);
}

Возвращает целочисленный код хэша для хеша.

Два объекта Hash имеют одинаковый код хэша, если их содержимое одинаковое (независимо от порядка):

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {baz: 2, bar: 1, foo: 0}
h2.hash == h1.hash # => true
h2.eql? h1 # => true
include?(key) → true or false Показать исходный код
MJIT_FUNC_EXPORTED VALUE
rb_hash_has_key(VALUE hash, VALUE key)
{
    return RBOOL(hash_stlike_lookup(hash, key, NULL));
}

Методы has_key?, key? и member? являются псевдонимами для #include?.

Возвращает true если key является ключом в self, в противном случае false.

Также алиасы: member?, has_key?, key?
initialize_copy(other_hash) -> self Показать исходный код
static VALUE
rb_hash_replace(VALUE hash, VALUE hash2)
{
    rb_hash_modify_check(hash);
    if (hash == hash2) return hash;
    if (RHASH_ITER_LEV(hash) > 0) {
        rb_raise(rb_eRuntimeError, "can't replace hash during iteration");
    }
    hash2 = to_hash(hash2);

    COPY_DEFAULT(hash, hash2);

    if (RHASH_AR_TABLE_P(hash)) {
        ar_free_and_clear_table(hash);
    }
    else {
        st_free_table(RHASH_ST_TABLE(hash));
        RHASH_ST_CLEAR(hash);
    }
    hash_copy(hash, hash2);
    if (RHASH_EMPTY_P(hash2) && RHASH_ST_TABLE_P(hash2)) {
        /* ident hash */
        RHASH_ST_TABLE_SET(hash, st_init_table_with_size(RHASH_TYPE(hash2), 0));
    }

    rb_gc_writebarrier_remember(hash);

    return hash;
}

Заменяет все содержимое self содержимым other_hash; возвращает self:

h = {foo: 0, bar: 1, baz: 2}
h.replace({bat: 3, bam: 4}) # => {:bat=>3, :bam=>4}
Также алиас: replace
inspect → new_string Показать исходный код
static VALUE
rb_hash_inspect(VALUE hash)
{
    if (RHASH_EMPTY_P(hash))
        return rb_usascii_str_new2("{}");
    return rb_exec_recursive(inspect_hash, hash, 0);
}

Возвращает новую строку, содержащую записи хеша:

h = {foo: 0, bar: 1, baz: 2}
h.inspect # => "{:foo=>0, :bar=>1, :baz=>2}"

Hash#to_s является псевдонимом для Hash#inspect.

Также алиас: to_s
invert → new_hash Показать исходный код
static VALUE
rb_hash_invert(VALUE hash)
{
    VALUE h = rb_hash_new_with_size(RHASH_SIZE(hash));

    rb_hash_foreach(hash, rb_hash_invert_i, h);
    return h;
}

Возвращает новый объект Hash с инвертированными парами ключ-значение:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.invert
h1 # => {0=>:foo, 1=>:bar, 2=>:baz}

Перезаписывает любые повторяющиеся новые ключи: (см. Порядок записей):

h = {foo: 0, bar: 0, baz: 0}
h.invert # => {0=>:baz}
keep_if {|key, value| ... } → self Показать исходный код
keep_if → new_enumerator
static VALUE
rb_hash_keep_if(VALUE hash)
{
    RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    rb_hash_modify_check(hash);
    if (!RHASH_TABLE_EMPTY_P(hash)) {
        rb_hash_foreach(hash, keep_if_i, hash);
    }
    return hash;
}

Вызывает блок для каждой пары ключ-значение; сохраняет запись, если блок возвращает истинное значение; в противном случае удаляет запись; возвращает self.

h = {foo: 0, bar: 1, baz: 2}
h.keep_if { |key, value| key.start_with?('b') } # => {:bar=>1, :baz=>2}

Возвращает новый Enumerator, если блок не указан:

h = {foo: 0, bar: 1, baz: 2}
e = h.keep_if # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:keep_if>
e.each { |key, value| key.start_with?('b') } # => {:bar=>1, :baz=>2}
key(value) → key or nil Показать исходный код
static VALUE
rb_hash_key(VALUE hash, VALUE value)
{
    VALUE args[2];

    args[0] = value;
    args[1] = Qnil;

    rb_hash_foreach(hash, key_i, (VALUE)args);

    return args[1];
}

Возвращает ключ для первой найденной записи со заданным value (см. Порядок записей):

h = {foo: 0, bar: 2, baz: 2}
h.key(0) # => :foo
h.key(2) # => :bar

Возвращает nil если такой ключ не найден.

key?(key) → true or false

Методы has_key?, key? и member? являются псевдонимами для #include?.

Возвращает true если key является ключом в self, в противном случае false.

Псевдоним для: include?
keys → new_array Показать исходный код
MJIT_FUNC_EXPORTED VALUE
rb_hash_keys(VALUE hash)
{
    st_index_t size = RHASH_SIZE(hash);
    VALUE keys =  rb_ary_new_capa(size);

    if (size == 0) return keys;

    if (ST_DATA_COMPATIBLE_P(VALUE)) {
        RARRAY_PTR_USE_TRANSIENT(keys, ptr, {
            if (RHASH_AR_TABLE_P(hash)) {
                size = ar_keys(hash, ptr, size);
            }
            else {
                st_table *table = RHASH_ST_TABLE(hash);
                size = st_keys(table, ptr, size);
            }
        });
        rb_gc_writebarrier_remember(keys);
        rb_ary_set_len(keys, size);
    }
    else {
        rb_hash_foreach(hash, keys_i, keys);
    }

    return keys;
}

Возвращает новый массив, содержащий все ключи в self:

h = {foo: 0, bar: 1, baz: 2}
h.keys # => [:foo, :bar, :baz]
length → integer

Возвращает количество записей в self:

{foo: 0, bar: 1, baz: 2}.length # => 3

Hash#length является псевдонимом для Hash#size.

Псевдоним для: size
member?(key) → true or false

Методы has_key?, key? и member? являются псевдонимами для #include?.

Возвращает true если key является ключом в self, в противном случае false.

Псевдоним для: include?
merge → copy_of_self Показать исходный код
merge(*other_hashes) → new_hash
merge(*other_hashes) { |key, old_value, new_value| ... } → new_hash
static VALUE
rb_hash_merge(int argc, VALUE *argv, VALUE self)
{
    return rb_hash_update(argc, argv, copy_compare_by_id(rb_hash_dup(self), self));
}

Возвращает новый объект Hash, сформированный путём слияния каждого из other_hashes в копию self.

Каждый аргумент в other_hashes должен быть объектом Hash.

С аргументами и без блока:

  • Возвращает новый объект Hash, сформированный путём слияния каждого последующего объекта Hash в other_hashes в self.

  • Каждая запись с новым ключом добавляется в конец.

  • Значение каждой записи с дублирующимся ключом перезаписывает предыдущее значение.

Пример:

h = {foo: 0, bar: 1, baz: 2}
h1 = {bat: 3, bar: 4}
h2 = {bam: 5, bat:6}
h.merge(h1, h2) # => {:foo=>0, :bar=>4, :baz=>2, :bat=>6, :bam=>5}

С аргументами и блоком:

  • Возвращает новый объект Hash, являющийся результатом слияния self и каждого из переданных объектов hash.

  • Переданные объекты hash сливаются слева направо.

  • Каждая запись с новым ключом добавляется в конец.

  • Для каждого дублирующегося ключа:

    • Вызывает блок с ключом и старым и новым значениями.

    • Возвращаемое значение блока становится новым значением для записи.

Пример:

h = {foo: 0, bar: 1, baz: 2}
h1 = {bat: 3, bar: 4}
h2 = {bam: 5, bat:6}
h3 = h.merge(h1, h2) { |key, old_value, new_value| old_value + new_value }
h3 # => {:foo=>0, :bar=>5, :baz=>2, :bat=>9, :bam=>5}

Без аргументов:

  • Возвращает копию self.

  • Блок, если он передан, игнорируется.

Пример:

h = {foo: 0, bar: 1, baz: 2}
h.merge # => {:foo=>0, :bar=>1, :baz=>2}
h1 = h.merge { |key, old_value, new_value| raise 'Cannot happen' }
h1 # => {:foo=>0, :bar=>1, :baz=>2}
merge! → self
merge!(*other_hashes) → self
merge!(*other_hashes) { |key, old_value, new_value| ... } → self

Объединяет каждый из other_hashes в self; возвращает self.

Каждый аргумент в other_hashes должен быть объектом Hash.

Метод update является псевдонимом для #merge!.

С аргументами и без блока:

  • Возвращает self, после слияния переданных объектов hash в него.

  • Переданные объекты hash сливаются слева направо.

  • Каждая новая запись добавляется в конец.

  • Значение каждой записи с дублирующимся ключом перезаписывает предыдущее значение.

Пример:

h = {foo: 0, bar: 1, baz: 2}
h1 = {bat: 3, bar: 4}
h2 = {bam: 5, bat:6}
h.merge!(h1, h2) # => {:foo=>0, :bar=>4, :baz=>2, :bat=>6, :bam=>5}

С аргументами и блоком:

  • Возвращает self, после слияния переданных объектов hash.

  • Переданные объекты hash сливаются слева направо.

  • Каждая запись с новым ключом добавляется в конец.

  • Для каждого дублирующегося ключа:

    • Вызывает блок с ключом и старым и новым значениями.

    • Возвращаемое значение блока становится новым значением для записи.

Пример:

h = {foo: 0, bar: 1, baz: 2}
h1 = {bat: 3, bar: 4}
h2 = {bam: 5, bat:6}
h3 = h.merge!(h1, h2) { |key, old_value, new_value| old_value + new_value }
h3 # => {:foo=>0, :bar=>5, :baz=>2, :bat=>9, :bam=>5}

Без аргументов:

  • Возвращает self, без изменений.

  • Блок, если он передан, игнорируется.

Пример:

h = {foo: 0, bar: 1, baz: 2}
h.merge # => {:foo=>0, :bar=>1, :baz=>2}
h1 = h.merge! { |key, old_value, new_value| raise 'Cannot happen' }
h1 # => {:foo=>0, :bar=>1, :baz=>2}
Псевдоним для: update
rassoc(value) → new_array or nil Показать исходный код
static VALUE
rb_hash_rassoc(VALUE hash, VALUE obj)
{
    VALUE args[2];

    args[0] = obj;
    args[1] = Qnil;
    rb_hash_foreach(hash, rassoc_i, (VALUE)args);
    return args[1];
}

Возвращает новый массив из 2 элементов, содержащий ключ и значение первой найденной записи, значение которой равно == значению (см. Порядок записей):

h = {foo: 0, bar: 1, baz: 1}
h.rassoc(1) # => [:bar, 1]

Возвращает nil если такое значение не найдено.

rehash → self Показать исходный код
VALUE
rb_hash_rehash(VALUE hash)
{
    VALUE tmp;
    st_table *tbl;

    if (RHASH_ITER_LEV(hash) > 0) {
        rb_raise(rb_eRuntimeError, "rehash during iteration");
    }
    rb_hash_modify_check(hash);
    if (RHASH_AR_TABLE_P(hash)) {
        tmp = hash_alloc(0);
        ar_alloc_table(tmp);
        rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
        ar_free_and_clear_table(hash);
        ar_copy(hash, tmp);
        ar_free_and_clear_table(tmp);
    }
    else if (RHASH_ST_TABLE_P(hash)) {
        st_table *old_tab = RHASH_ST_TABLE(hash);
        tmp = hash_alloc(0);
        tbl = st_init_table_with_size(old_tab->type, old_tab->num_entries);
        RHASH_ST_TABLE_SET(tmp, tbl);
        rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
        st_free_table(old_tab);
        RHASH_ST_TABLE_SET(hash, tbl);
        RHASH_ST_CLEAR(tmp);
    }
    hash_verify(hash);
    return hash;
}

Перестраивает таблицу хэширования, пересчитывая индекс хэша для каждого ключа; возвращает self.

Таблица хэширования становится недействительной, если значение хэша ключа изменилось после создания записи. См. Изменение активного ключа хэша.

reject {|key, value| ... } → new_hash Показать исходный код
reject → new_enumerator
static VALUE
rb_hash_reject(VALUE hash)
{
    VALUE result;

    RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    result = hash_dup_with_compare_by_id(hash);
    if (!RHASH_EMPTY_P(hash)) {
        rb_hash_foreach(result, delete_if_i, result);
    }
    return result;
}

Возвращает новый объект Hash, чьи записи - все записи из self, для которых блок возвращает false или nil:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.reject {|key, value| key.start_with?('b') }
h1 # => {:foo=>0}

Возвращает новый перечислитель, если блок не передан:

h = {foo: 0, bar: 1, baz: 2}
e = h.reject # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:reject>
h1 = e.each {|key, value| key.start_with?('b') }
h1 # => {:foo=>0}
reject! {|key, value| ... } → self or nil Показать исходный код
reject! → new_enumerator
static VALUE
rb_hash_reject_bang(VALUE hash)
{
    st_index_t n;

    RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    rb_hash_modify(hash);
    n = RHASH_SIZE(hash);
    if (!n) return Qnil;
    rb_hash_foreach(hash, delete_if_i, hash);
    if (n == RHASH_SIZE(hash)) return Qnil;
    return hash;
}

Возвращает self, оставшиеся записи которого - те, для которых блок возвращает false или nil:

h = {foo: 0, bar: 1, baz: 2}
h.reject! {|key, value| value < 2 } # => {:baz=>2}

Возвращает nil если записи не удалены.

Возвращает новый перечислитель, если блок не передан:

h = {foo: 0, bar: 1, baz: 2}
e = h.reject! # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:reject!>
e.each {|key, value| key.start_with?('b') } # => {:foo=>0}
replace(other_hash) → self

Заменяет все содержимое self содержимым other_hash; возвращает self:

h = {foo: 0, bar: 1, baz: 2}
h.replace({bat: 3, bam: 4}) # => {:bat=>3, :bam=>4}
Псевдоним для: initialize_copy
select {|key, value| ... } → new_hash Показать исходный код
select → new_enumerator
static VALUE
rb_hash_select(VALUE hash)
{
    VALUE result;

    RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    result = hash_dup_with_compare_by_id(hash);
    if (!RHASH_EMPTY_P(hash)) {
        rb_hash_foreach(result, keep_if_i, result);
    }
    return result;
}

Hash#filter является псевдонимом для Hash#select.

Возвращает новый объект Hash, чьи записи - те, для которых блок возвращает истинное значение:

h = {foo: 0, bar: 1, baz: 2}
h.select {|key, value| value < 2 } # => {:foo=>0, :bar=>1}

Возвращает новый перечислитель, если блок не передан:

h = {foo: 0, bar: 1, baz: 2}
e = h.select # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:select>
e.each {|key, value| value < 2 } # => {:foo=>0, :bar=>1}
Также псевдоним: filter
select! {|key, value| ... } → self or nil Показать исходный код
select! → new_enumerator
static VALUE
rb_hash_select_bang(VALUE hash)
{
    st_index_t n;

    RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    rb_hash_modify_check(hash);
    n = RHASH_SIZE(hash);
    if (!n) return Qnil;
    rb_hash_foreach(hash, keep_if_i, hash);
    if (n == RHASH_SIZE(hash)) return Qnil;
    return hash;
}

Hash#filter! является псевдонимом для Hash#select!.

Возвращает self, чьи записи - те, для которых блок возвращает истинное значение:

h = {foo: 0, bar: 1, baz: 2}
h.select! {|key, value| value < 2 }  => {:foo=>0, :bar=>1}

Возвращает nil если записи не удалены.

Возвращает новый перечислитель, если блок не передан:

h = {foo: 0, bar: 1, baz: 2}
e = h.select!  # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:select!>
e.each { |key, value| value < 2 } # => {:foo=>0, :bar=>1}
Также псевдоним: filter!
shift → [key, value] or nil Показать исходный код
static VALUE
rb_hash_shift(VALUE hash)
{
    struct shift_var var;

    rb_hash_modify_check(hash);
    if (RHASH_AR_TABLE_P(hash)) {
        var.key = Qundef;
        if (RHASH_ITER_LEV(hash) == 0) {
            if (ar_shift(hash, &var.key, &var.val)) {
                return rb_assoc_new(var.key, var.val);
            }
        }
        else {
            rb_hash_foreach(hash, shift_i_safe, (VALUE)&var);
            if (!UNDEF_P(var.key)) {
                rb_hash_delete_entry(hash, var.key);
                return rb_assoc_new(var.key, var.val);
            }
        }
    }
    if (RHASH_ST_TABLE_P(hash)) {
        var.key = Qundef;
        if (RHASH_ITER_LEV(hash) == 0) {
            if (st_shift(RHASH_ST_TABLE(hash), &var.key, &var.val)) {
                return rb_assoc_new(var.key, var.val);
            }
        }
        else {
            rb_hash_foreach(hash, shift_i_safe, (VALUE)&var);
            if (!UNDEF_P(var.key)) {
                rb_hash_delete_entry(hash, var.key);
                return rb_assoc_new(var.key, var.val);
            }
        }
    }
    return Qnil;
}

Удаляет первую запись хэша (см. Порядок записей); возвращает массив из 2 элементов, содержащий удалённый ключ и значение:

h = {foo: 0, bar: 1, baz: 2}
h.shift # => [:foo, 0]
h # => {:bar=>1, :baz=>2}

Возвращает nil если хэш пуст.

size → integer Показать исходный код
VALUE
rb_hash_size(VALUE hash)
{
    return INT2FIX(RHASH_SIZE(hash));
}

Возвращает количество записей в self:

{foo: 0, bar: 1, baz: 2}.length # => 3

Hash#length является псевдонимом для Hash#size.

Также псевдоним: length
slice(*keys) → new_hash Показать исходный код
static VALUE
rb_hash_slice(int argc, VALUE *argv, VALUE hash)
{
    int i;
    VALUE key, value, result;

    if (argc == 0 || RHASH_EMPTY_P(hash)) {
        return copy_compare_by_id(rb_hash_new(), hash);
    }
    result = copy_compare_by_id(rb_hash_new_with_size(argc), hash);

    for (i = 0; i < argc; i++) {
        key = argv[i];
        value = rb_hash_lookup2(hash, key, Qundef);
        if (!UNDEF_P(value))
            rb_hash_aset(result, key, value);
    }

    return result;
}

Возвращает новый объект Hash, содержащий записи для указанных keys:

h = {foo: 0, bar: 1, baz: 2}
h.slice(:baz, :foo) # => {:baz=>2, :foo=>0}

Любые переданные keys которые не найдены игнорируются.

END_OF_DOCUMENT_MARKER
store(key, value)

Hash#store является псевдонимом для Hash#[]=.

Связывает заданное value с заданным key; возвращает value.

Если заданное key существует, заменяет его значение заданным value; порядок не изменяется (см. Порядок элементов):

h = {foo: 0, bar: 1}
h[:foo] = 2 # => 2
h.store(:bar, 3) # => 3
h # => {:foo=>2, :bar=>3}

Если заданное key не существует, добавляет key и value; новая запись размещается последней в порядке (см. Порядок элементов):

h = {foo: 0, bar: 1}
h[:baz] = 2 # => 2
h.store(:bat, 3) # => 3
h # => {:foo=>0, :bar=>1, :baz=>2, :bat=>3}
Псевдоним для: []=
to_a → new_array Показать исходный код
static VALUE
rb_hash_to_a(VALUE hash)
{
    VALUE ary;

    ary = rb_ary_new_capa(RHASH_SIZE(hash));
    rb_hash_foreach(hash, to_a_i, ary);

    return ary;
}

Возвращает новый массив объектов массивов из двух элементов; каждый вложенный массив содержит пару ключ-значение из self:

h = {foo: 0, bar: 1, baz: 2}
h.to_a # => [[:foo, 0], [:bar, 1], [:baz, 2]]
to_h → self or new_hash Показать исходный код
to_h {|key, value| ... } → new_hash
static VALUE
rb_hash_to_h(VALUE hash)
{
    if (rb_block_given_p()) {
        return rb_hash_to_h_block(hash);
    }
    if (rb_obj_class(hash) != rb_cHash) {
        const VALUE flags = RBASIC(hash)->flags;
        hash = hash_dup(hash, rb_cHash, flags & RHASH_PROC_DEFAULT);
    }
    return hash;
}

Для экземпляра Hash возвращает self.

Для подкласса Hash возвращает новый Hash, содержащий содержимое self.

При передаче блока возвращает новый объект Hash, содержимое которого основано на блоке; блок должен возвращать объект массива из двух элементов, определяющий пару ключ-значение, которая должна быть включена в возвращаемый массив:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.to_h {|key, value| [value, key] }
h1 # => {0=>:foo, 1=>:bar, 2=>:baz}
to_hash → self Показать исходный код
static VALUE
rb_hash_to_hash(VALUE hash)
{
    return hash;
}

Возвращает self.

to_proc → proc Показать исходный код
static VALUE
rb_hash_to_proc(VALUE hash)
{
    return rb_func_lambda_new(hash_proc_call, hash, 1, 1);
}

Возвращает объект Proc, который сопоставляет ключ со своим значением:

h = {foo: 0, bar: 1, baz: 2}
proc = h.to_proc
proc.class # => Proc
proc.call(:foo) # => 0
proc.call(:bar) # => 1
proc.call(:nosuch) # => nil
to_s()

Возвращает новую строку, содержащую записи хеша:

h = {foo: 0, bar: 1, baz: 2}
h.inspect # => "{:foo=>0, :bar=>1, :baz=>2}"

Hash#to_s является псевдонимом для Hash#inspect.

Псевдоним для: inspect
transform_keys {|key| ... } → new_hash Показать исходный код
transform_keys(hash2) → new_hash
transform_keys(hash2) {|other_key| ...} → new_hash
transform_keys → new_enumerator
static VALUE
rb_hash_transform_keys(int argc, VALUE *argv, VALUE hash)
{
    VALUE result;
    struct transform_keys_args transarg = {0};

    argc = rb_check_arity(argc, 0, 1);
    if (argc > 0) {
        transarg.trans = to_hash(argv[0]);
        transarg.block_given = rb_block_given_p();
    }
    else {
        RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    }
    result = rb_hash_new();
    if (!RHASH_EMPTY_P(hash)) {
        if (transarg.trans) {
            transarg.result = result;
            rb_hash_foreach(hash, transform_keys_hash_i, (VALUE)&transarg);
        }
        else {
            rb_hash_foreach(hash, transform_keys_i, result);
        }
    }

    return result;
}

Возвращает новый объект Hash; каждая запись имеет:

  • Ключ, предоставленный блоком.

  • Значение из self.

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

Преобразование ключей:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.transform_keys {|key| key.to_s }
h1 # => {"foo"=>0, "bar"=>1, "baz"=>2}

h.transform_keys(foo: :bar, bar: :foo)
#=> {bar: 0, foo: 1, baz: 2}

h.transform_keys(foo: :hello, &:to_s)
#=> {:hello=>0, "bar"=>1, "baz"=>2}

Перезаписывает значения для дублирующих ключей:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.transform_keys {|key| :bat }
h1 # => {:bat=>2}

Возвращает новый перечислитель, если блок не указан:

h = {foo: 0, bar: 1, baz: 2}
e = h.transform_keys # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:transform_keys>
h1 = e.each { |key| key.to_s }
h1 # => {"foo"=>0, "bar"=>1, "baz"=>2}
transform_keys! {|key| ... } → self Показать исходный код
transform_keys!(hash2) → self
transform_keys!(hash2) {|other_key| ...} → self
transform_keys! → new_enumerator
static VALUE
rb_hash_transform_keys_bang(int argc, VALUE *argv, VALUE hash)
{
    VALUE trans = 0;
    int block_given = 0;

    argc = rb_check_arity(argc, 0, 1);
    if (argc > 0) {
        trans = to_hash(argv[0]);
        block_given = rb_block_given_p();
    }
    else {
        RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    }
    rb_hash_modify_check(hash);
    if (!RHASH_TABLE_EMPTY_P(hash)) {
        long i;
        VALUE new_keys = hash_alloc(0);
        VALUE pairs = rb_ary_hidden_new(RHASH_SIZE(hash) * 2);
        rb_hash_foreach(hash, flatten_i, pairs);
        for (i = 0; i < RARRAY_LEN(pairs); i += 2) {
            VALUE key = RARRAY_AREF(pairs, i), new_key, val;

            if (!trans) {
                new_key = rb_yield(key);
            }
            else if (!UNDEF_P(new_key = rb_hash_lookup2(trans, key, Qundef))) {
                /* use the transformed key */
            }
            else if (block_given) {
                new_key = rb_yield(key);
            }
            else {
                new_key = key;
            }
            val = RARRAY_AREF(pairs, i+1);
            if (!hash_stlike_lookup(new_keys, key, NULL)) {
                rb_hash_stlike_delete(hash, &key, NULL);
            }
            rb_hash_aset(hash, new_key, val);
            rb_hash_aset(new_keys, new_key, Qnil);
        }
        rb_ary_clear(pairs);
        rb_hash_clear(new_keys);
    }
    return hash;
}

То же самое, что и Hash#transform_keys, но изменяет получателя на месте вместо возврата нового хеша.

transform_values {|value| ... } → new_hash Показать исходный код
transform_values → new_enumerator
static VALUE
rb_hash_transform_values(VALUE hash)
{
    VALUE result;

    RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    result = hash_dup_with_compare_by_id(hash);
    SET_DEFAULT(result, Qnil);

    if (!RHASH_EMPTY_P(hash)) {
        rb_hash_stlike_foreach_with_replace(result, transform_values_foreach_func, transform_values_foreach_replace, result);
    }

    return result;
}

Возвращает новый объект Hash; каждая запись имеет:

  • Ключ из self.

  • Значение, предоставленное блоком.

Преобразование значений:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.transform_values {|value| value * 100}
h1 # => {:foo=>0, :bar=>100, :baz=>200}

Возвращает новый перечислитель, если блок не указан:

h = {foo: 0, bar: 1, baz: 2}
e = h.transform_values # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:transform_values>
h1 = e.each { |value| value * 100}
h1 # => {:foo=>0, :bar=>100, :baz=>200}
transform_values! {|value| ... } → self Показать исходный код
transform_values! → new_enumerator
static VALUE
rb_hash_transform_values_bang(VALUE hash)
{
    RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    rb_hash_modify_check(hash);

    if (!RHASH_TABLE_EMPTY_P(hash)) {
        rb_hash_stlike_foreach_with_replace(hash, transform_values_foreach_func, transform_values_foreach_replace, hash);
    }

    return hash;
}

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

h = {foo: 0, bar: 1, baz: 2}
h.transform_values! {|value| value * 100} # => {:foo=>0, :bar=>100, :baz=>200}

Возвращает новый перечислитель, если блок не указан:

h = {foo: 0, bar: 1, baz: 2}
e = h.transform_values! # => #<Enumerator: {:foo=>0, :bar=>100, :baz=>200}:transform_values!>
h1 = e.each {|value| value * 100}
h1 # => {:foo=>0, :bar=>100, :baz=>200}
update(*other_hashes) { |key, old_value, new_value| } -> self Показать исходный код
static VALUE
rb_hash_update(int argc, VALUE *argv, VALUE self)
{
    int i;
    bool block_given = rb_block_given_p();

    rb_hash_modify(self);
    for (i = 0; i < argc; i++){
        VALUE hash = to_hash(argv[i]);
        if (block_given) {
            rb_hash_foreach(hash, rb_hash_update_block_i, self);
        }
        else {
            rb_hash_foreach(hash, rb_hash_update_i, self);
        }
    }
    return self;
}

Объединяет каждый из other_hashes в self; возвращает self.

Каждый аргумент в other_hashes должен быть объектом Hash.

Метод update является псевдонимом для #merge!.

С аргументами и без блока:

  • Возвращает self, после объединения переданных хешей в него.

  • Переданные хеши объединяются слева направо.

  • Каждая новая запись добавляется в конец.

  • Значение каждой записи с дублирующим ключом перезаписывает предыдущее значение.

Пример:

h = {foo: 0, bar: 1, baz: 2}
h1 = {bat: 3, bar: 4}
h2 = {bam: 5, bat:6}
h.merge!(h1, h2) # => {:foo=>0, :bar=>4, :baz=>2, :bat=>6, :bam=>5}

С аргументами и блоком:

  • Возвращает self, после объединения переданных хешей.

  • Переданные хеши объединяются слева направо.

  • Каждая запись с новым ключом добавляется в конец.

  • Для каждого дублирующего ключа:

    • Вызывает блок с ключом и старым и новым значениями.

    • Возвращаемое значение блока становится новым значением для записи.

Пример:

h = {foo: 0, bar: 1, baz: 2}
h1 = {bat: 3, bar: 4}
h2 = {bam: 5, bat:6}
h3 = h.merge!(h1, h2) { |key, old_value, new_value| old_value + new_value }
h3 # => {:foo=>0, :bar=>5, :baz=>2, :bat=>9, :bam=>5}

Без аргументов:

  • Возвращает self, без изменений.

  • Блок, если он передан, игнорируется.

Пример:

h = {foo: 0, bar: 1, baz: 2}
h.merge # => {:foo=>0, :bar=>1, :baz=>2}
h1 = h.merge! { |key, old_value, new_value| raise 'Cannot happen' }
h1 # => {:foo=>0, :bar=>1, :baz=>2}
Также алиасирован как: merge!
value?(value) → true or false

Method value? является псевдонимом для #has_value?.

Возвращает true если value является значением в self, в противном случае false.

Псевдоним для: has_value?
values → new_array Показать исходный код
VALUE
rb_hash_values(VALUE hash)
{
    VALUE values;
    st_index_t size = RHASH_SIZE(hash);

    values = rb_ary_new_capa(size);
    if (size == 0) return values;

    if (ST_DATA_COMPATIBLE_P(VALUE)) {
        if (RHASH_AR_TABLE_P(hash)) {
            rb_gc_writebarrier_remember(values);
            RARRAY_PTR_USE_TRANSIENT(values, ptr, {
                size = ar_values(hash, ptr, size);
            });
        }
        else if (RHASH_ST_TABLE_P(hash)) {
            st_table *table = RHASH_ST_TABLE(hash);
            rb_gc_writebarrier_remember(values);
            RARRAY_PTR_USE_TRANSIENT(values, ptr, {
                size = st_values(table, ptr, size);
            });
        }
        rb_ary_set_len(values, size);
    }

    else {
        rb_hash_foreach(hash, values_i, values);
    }

    return values;
}

Возвращает новый массив, содержащий все значения в self:

h = {foo: 0, bar: 1, baz: 2}
h.values # => [0, 1, 2]
values_at(*keys) → new_array Показать исходный код
static VALUE
rb_hash_values_at(int argc, VALUE *argv, VALUE hash)
{
    VALUE result = rb_ary_new2(argc);
    long i;

    for (i=0; i<argc; i++) {
        rb_ary_push(result, rb_hash_aref(hash, argv[i]));
    }
    return result;
}

Возвращает новый массив, содержащий значения для заданных keys:

h = {foo: 0, bar: 1, baz: 2}
h.values_at(:baz, :foo) # => [2, 0]

Значения по умолчанию возвращаются для ключей, которые не найдены:

h.values_at(:hello, :foo) # => [nil, 0]

Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

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