A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://docs.ruby-lang.org/en/3.0/Hash.html below:

class Hash - RDoc Documentation

class Hash

A Hash maps each of its unique keys to a specific value.

A Hash has certain similarities to an Array, but:

Hash Data Syntax

The older syntax for Hash data uses the “hash rocket,” =>:

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

Alternatively, but only for a Hash key that's a Symbol, you can use a newer JSON-style syntax, where each bareword becomes a Symbol:

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

You can also use a String in place of a bareword:

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

And you can mix the styles:

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

But it's an error to try the JSON-style syntax for a key that's not a bareword or a String:

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

You can use a Hash to give names to objects:

person = {name: 'Matz', language: 'Ruby'}
person 

You can use a Hash to give names to method arguments:

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

Note: when the last argument in a method call is a Hash, the curly braces may be omitted:

some_method(foo: 0, bar: 1, baz: 2) 

You can use a Hash to initialize an object:

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 
Creating a Hash

Here are three ways to create a Hash:

You can create a Hash by calling method Hash.new.

Create an empty Hash:

h = Hash.new
h 
h.class 

You can create a Hash by calling method Hash.[].

Create an empty Hash:

h = Hash[]
h 

Create a Hash with initial entries:

h = Hash[foo: 0, bar: 1, baz: 2]
h 

You can create a Hash by using its literal form (curly braces).

Create an empty Hash:

h = {}
h 

Create a Hash with initial entries:

h = {foo: 0, bar: 1, baz: 2}
h 
Hash Value Basics

The simplest way to retrieve a Hash value (instance method []):

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

The simplest way to create or update a Hash value (instance method []=):

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

The simplest way to delete a Hash entry (instance method delete):

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

A Hash object presents its entries in the order of their creation. This is seen in:

A new Hash has its initial ordering per the given entries:

h = Hash[foo: 0, bar: 1]
h 

New entries are added at the end:

h[:baz] = 2
h 

Updating a value does not affect the order:

h[:baz] = 3
h 

But re-creating a deleted entry can affect the order:

h.delete(:foo)
h[:foo] = 5
h 
Hash Keys Hash Key Equivalence

Two objects are treated as the same hash key when their hash value is identical and the two objects are eql? to each other.

Modifying an Active Hash Key

Modifying a Hash key while it is in use damages the hash's index.

This Hash has keys that are Arrays:

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

Modifying array element a0[0] changes its hash value:

a0[0] = :bam
a0.hash 

And damages the Hash index:

h.include?(a0) 
h[a0] 

You can repair the hash index using method rehash:

h.rehash 
h.include?(a0) 
h[a0] 

A String key is always safe. That's because an unfrozen String passed as a key will be replaced by a duplicated and frozen String:

s = 'foo'
s.frozen? 
h = {s => 0}
first_key = h.keys.first
first_key.frozen? 
User-Defined Hash Keys

To be useable as a Hash key, objects must implement the methods hash and eql?. Note: this requirement does not apply if the Hash uses compare_by_id since comparison will then rely on the keys' object id instead of hash and eql?.

Object defines basic implementation for hash and eq? that makes each object a distinct key. Typically, user-defined classes will want to override these methods to provide meaningful behavior, or for example inherit Struct that has useful definitions for these.

A typical implementation of hash is based on the object's data while eql? is usually aliased to the overridden == method:

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 
  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 
Default Values

The methods [], values_at and dig need to return the value associated to a certain key. When that key is not found, that value will be determined by its default proc (if any) or else its default (initially `nil`).

You can retrieve the default value with method default:

h = Hash.new
h.default 

You can set the default value by passing an argument to method Hash.new or with method default=

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

This default value is returned for [], values_at and dig when a key is not found:

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

Note that the default value is used without being duplicated. It is not advised to set the default value to a mutable object:

synonyms = Hash.new([])
synonyms[:hello] 
synonyms[:hello] << :hi 
synonyms.default 
synonyms[:world] << :universe
synonyms[:world] 
synonyms.keys 

To use a mutable object as default, it is recommended to use a default proc

Default Proc

When the default proc for a Hash is set (i.e., not nil), the default value returned by method [] is determined by the default proc alone.

You can retrieve the default proc with method default_proc:

h = Hash.new
h.default_proc 

You can set the default proc by calling Hash.new with a block or calling the method default_proc=

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

When the default proc is set (i.e., not nil) and method [] is called with with a non-existent key, [] calls the default proc with both the Hash object itself and the missing key, then returns the proc's return value:

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

Note that in the example above no entry for key :nosuch is created:

h.include?(:nosuch) 

However, the proc itself can add a new entry:

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

Note that setting the default proc will clear the default value and vice versa.

Public Class Methods

Hash[] → new_empty_hash click to toggle source

Hash[hash] → new_hash

Hash[ [*2_element_arrays] ] → new_hash

Hash[*objects] → new_hash

Returns a new Hash object populated with the given objects, if any. See Hash::new.

With no argument, returns a new empty Hash.

When the single given argument is a Hash, returns a new Hash populated with the entries from the given Hash.

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

When the single given argument is an Array of 2-element Arrays, returns a new Hash object wherein each 2-element array forms a key-value entry:

Hash[ [ [:foo, 0], [:bar, 1] ] ] 

When the argument count is an even number; returns a new Hash object wherein each successive pair of arguments has become a key-value entry:

Hash[:foo, 0, :bar, 1] 

Raises an exception if the argument list does not conform to any of the above.

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;
}

new(default_value = nil) → new_hash click to toggle source

new {|hash, key| ... } → new_hash

Returns a new empty Hash object.

The initial default value and initial default proc for the new hash depend on which form above was used. See Default Values.

If neither an argument nor a block given, initializes both the default value and the default proc to nil:

h = Hash.new
h.default 
h.default_proc 

If argument default_value given but no block given, initializes the default value to the given default_value and the default proc to nil:

h = Hash.new(false)
h.default 
h.default_proc 

If a block given but no argument, stores the block as the default proc and sets the default value to nil:

h = Hash.new {|hash, key| "Default value for #{key}" }
h.default 
h.default_proc.class 
h[:nosuch] 
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;
}

ruby2_keywords_hash(hash) → hash click to toggle source

Duplicates a given hash and adds a ruby2_keywords flag. This method is not for casual use; debugging, researching, and some truly necessary cases like deserialization of arguments.

h = {k: 1}
h = Hash.ruby2_keywords_hash(h)
def foo(k: 42)
  k
end
foo(*[h]) 
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;
}

ruby2_keywords_hash?(hash) → true or false click to toggle source

Checks if a given hash is flagged by Module#ruby2_keywords (or Proc#ruby2_keywords). This method is not for casual use; debugging, researching, and some truly necessary cases like serialization of arguments.

ruby2_keywords def foo(*args)
  Hash.ruby2_keywords_hash?(args.last)
end
foo(k: 1)   
foo({k: 1}) 
static VALUE
rb_hash_s_ruby2_keywords_hash_p(VALUE dummy, VALUE hash)
{
    Check_Type(hash, T_HASH);
    return (RHASH(hash)->basic.flags & RHASH_PASS_AS_KEYWORDS) ? Qtrue : Qfalse;
}

try_convert(obj) → obj, new_hash, or nil click to toggle source

If obj is a Hash object, returns obj.

Otherwise if obj responds to :to_hash, calls obj.to_hash and returns the result.

Returns nil if obj does not respond to :to_hash

Raises an exception unless obj.to_hash returns a Hash object.

static VALUE
rb_hash_s_try_convert(VALUE dummy, VALUE hash)
{
    return rb_check_hash_type(hash);
}
Public Instance Methods

hash < other_hash → true or false click to toggle source

Returns true if hash is a proper subset of other_hash, false otherwise:

h1 = {foo: 0, bar: 1}
h2 = {foo: 0, bar: 1, baz: 2}
h1 < h2 
h2 < h1 
h1 < h1 
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);
}

hash <= other_hash → true or false click to toggle source

Returns true if hash is a subset of other_hash, false otherwise:

h1 = {foo: 0, bar: 1}
h2 = {foo: 0, bar: 1, baz: 2}
h1 <= h2 
h2 <= h1 
h1 <= h1 
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);
}

hash == object → true or false click to toggle source

Returns true if all of the following are true:

Otherwise, returns false.

Equal:

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {foo: 0, bar: 1, baz: 2}
h1 == h2 
h3 = {baz: 2, bar: 1, foo: 0}
h1 == h3 
static VALUE
rb_hash_equal(VALUE hash1, VALUE hash2)
{
    return hash_equal(hash1, hash2, FALSE);
}

hash > other_hash → true or false click to toggle source

Returns true if hash is a proper superset of other_hash, false otherwise:

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {foo: 0, bar: 1}
h1 > h2 
h2 > h1 
h1 > h1 
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);
}

hash >= other_hash → true or false click to toggle source

Returns true if hash is a superset of other_hash, false otherwise:

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {foo: 0, bar: 1}
h1 >= h2 
h2 >= h1 
h1 >= h1 
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);
}

hash[key] → value click to toggle source

Returns the value associated with the given key, if found:

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

If key is not found, returns a default value (see Default Values):

h = {foo: 0, bar: 1, baz: 2}
h[:nosuch] 
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);
    }
}

hash[key] = value → value click to toggle source

Hash#store is an alias for Hash#[]=.

Associates the given value with the given key; returns value.

If the given key exists, replaces its value with the given value; the ordering is not affected (see Entry Order):

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

If key does not exist, adds the key and value; the new entry is last in the order (see Entry Order):

h = {foo: 0, bar: 1}
h[:baz] = 2 
h.store(:bat, 3) 
h 
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;
}

any? → true or false click to toggle source

any?(object) → true or false

any? {|key, value| ... } → true or false

Returns true if any element satisfies a given criterion; false otherwise.

With no argument and no block, returns true if self is non-empty; false if empty.

With argument object and no block, returns true if for any key key h.assoc(key) == object:

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

With no argument and a block, calls the block with each key-value pair; returns true if the block returns any truthy value, false otherwise:

h = {foo: 0, bar: 1, baz: 2}
h.any? {|key, value| value < 3 } 
h.any? {|key, value| value > 3 } 
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];
}

assoc(key) → new_array or nil click to toggle source

If the given key is found, returns a 2-element Array containing that key and its value:

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

Returns nil if key key is not found.

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 (value != Qundef) return rb_assoc_new(key, value);
    }

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

clear → self click to toggle source

Removes all hash entries; returns 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;
}

compact → new_hash click to toggle source

Returns a copy of self with all nil-valued entries removed:

h = {foo: 0, bar: nil, baz: 2, bat: nil}
h1 = h.compact
h1 
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;
}

compact! → self or nil click to toggle source

Returns self with all its nil-valued entries removed (in place):

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

Returns nil if no entries were removed.

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;
}

compare_by_identity → self click to toggle source

Sets self to consider only identity in comparing keys; two keys are considered the same only if they are the same object; returns self.

By default, these two object are considered to be the same key, so s1 will overwrite s0:

s0 = 'x'
s1 = 'x'
h = {}
h.compare_by_identity? 
h[s0] = 0
h[s1] = 1
h 

After calling #compare_by_identity, the keys are considered to be different, and therefore do not overwrite each other:

h = {}
h.compare_by_identity 
h.compare_by_identity? 
h[s0] = 0
h[s1] = 1
h 
static 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);
    rb_gc_force_recycle(tmp);

    return hash;
}

compare_by_identity? → true or false click to toggle source

Returns true if compare_by_identity has been called, false otherwise.

MJIT_FUNC_EXPORTED VALUE
rb_hash_compare_by_id_p(VALUE hash)
{
    if (RHASH_ST_TABLE_P(hash) && RHASH_ST_TABLE(hash)->type == &identhash) {
        return Qtrue;
    }
    else {
        return Qfalse;
    }
}

deconstruct_keys(p1) click to toggle source

static VALUE
rb_hash_deconstruct_keys(VALUE hash, VALUE keys)
{
    return hash;
}

default → object click to toggle source

default(key) → object

Returns the default value for the given key. The returned value will be determined either by the default proc or by the default value. See Default Values.

With no argument, returns the current default value:

h = {}
h.default 

If key is given, returns the default value for key, regardless of whether that key exists:

h = Hash.new { |hash, key| hash[key] = "No key #{key}"}
h[:foo] = "Hello"
h.default(:foo) 
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;
}

default = value → object click to toggle source

Sets the default value to value; returns value:

h = {}
h.default 
h.default = false 
h.default 

See Default Values.

static VALUE
rb_hash_set_default(VALUE hash, VALUE ifnone)
{
    rb_hash_modify_check(hash);
    SET_DEFAULT(hash, ifnone);
    return ifnone;
}

default_proc → proc or nil click to toggle source

Returns the default proc for self (see Default Values):

h = {}
h.default_proc 
h.default_proc = proc {|hash, key| "Default value for #{key}" }
h.default_proc.class 
static VALUE
rb_hash_default_proc(VALUE hash)
{
    if (FL_TEST(hash, RHASH_PROC_DEFAULT)) {
        return RHASH_IFNONE(hash);
    }
    return Qnil;
}

default_proc = proc → proc click to toggle source

Sets the default proc for self to proc: (see Default Values):

h = {}
h.default_proc 
h.default_proc = proc { |hash, key| "Default value for #{key}" }
h.default_proc.class 
h.default_proc = nil
h.default_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;
}

delete(key) → value or nil click to toggle source

delete(key) {|key| ... } → object

Deletes the entry for the given key and returns its associated value.

If no block is given and key is found, deletes the entry and returns the associated value:

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

If no block given and key is not found, returns nil.

If a block is given and key is found, ignores the block, deletes the entry, and returns the associated value:

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

If a block is given and key is not found, calls the block and returns the block's return value:

h = {foo: 0, bar: 1, baz: 2}
h.delete(:nosuch) { |key| "Key #{key} not found" } 
h 
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 (val != Qundef) {
        return val;
    }
    else {
        if (rb_block_given_p()) {
            return rb_yield(key);
        }
        else {
            return Qnil;
        }
    }
}

delete_if {|key, value| ... } → self click to toggle source

delete_if → new_enumerator

If a block given, calls the block with each key-value pair; deletes each entry for which the block returns a truthy value; returns self:

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

If no block given, returns a new Enumerator:

h = {foo: 0, bar: 1, baz: 2}
e = h.delete_if 
e.each { |key, value| value > 0 } 
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;
}

dig(key, *identifiers) → object click to toggle source

Finds and returns the object in nested objects that is specified by key and identifiers. The nested objects may be instances of various classes. See Dig Methods.

Nested Hashes:

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

Nested Hashes and Arrays:

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

This method will use the default values for keys that are not present:

h = {foo: {bar: [:a, :b, :c]}}
h.dig(:hello) 
h.default_proc = -> (hash, _key) { hash }
h.dig(:hello, :world) 
h.dig(:hello, :world, :foo, :bar, 2) 
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);
}

each {|key, value| ... } → self

each → new_enumerator

Hash#each is an alias for Hash#each_pair.

Calls the given block with each key-value pair; returns self:

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

Output:

foo: 0
bar: 1
baz: 2

Returns a new Enumerator if no block given:

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

Output:

foo: 0
bar: 1
baz: 2

each_key {|key| ... } → self click to toggle source

each_key → new_enumerator

Calls the given block with each key; returns self:

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

Output:

foo
bar
baz

Returns a new Enumerator if no block given:

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

Output:

foo
bar
baz
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;
}

Hash#each is an alias for Hash#each_pair.

Calls the given block with each key-value pair; returns self:

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

Output:

foo: 0
bar: 1
baz: 2

Returns a new Enumerator if no block given:

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

Output:

foo: 0
bar: 1
baz: 2
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;
}

each_value {|value| ... } → self click to toggle source

each_value → new_enumerator

Calls the given block with each value; returns self:

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

Output:

0
1
2

Returns a new Enumerator if no block given:

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

Output:

0
1
2
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;
}

empty? → true or false click to toggle source

Returns true if there are no hash entries, false otherwise:

{}.empty? 
{foo: 0, bar: 1, baz: 2}.empty? 
static VALUE
rb_hash_empty_p(VALUE hash)
{
    return RHASH_EMPTY_P(hash) ? Qtrue : Qfalse;
}

eql? object → true or false click to toggle source

Returns true if all of the following are true:

Otherwise, returns false.

Equal:

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {foo: 0, bar: 1, baz: 2}
h1.eql? h2 
h3 = {baz: 2, bar: 1, foo: 0}
h1.eql? h3 
static VALUE
rb_hash_eql(VALUE hash1, VALUE hash2)
{
    return hash_equal(hash1, hash2, TRUE);
}

except(*keys) → a_hash click to toggle source

Returns a new Hash excluding entries for the given keys:

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

Any given keys that are not found are ignored.

static VALUE
rb_hash_except(int argc, VALUE *argv, VALUE hash)
{
    int i;
    VALUE key, result;

    result = hash_alloc(rb_cHash);
    hash_copy(result, hash);

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

    return result;
}

fetch(key) → object click to toggle source

fetch(key, default_value) → object

fetch(key) {|key| ... } → object

Returns the value for the given key, if found.

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

If key is not found and no block was given, returns default_value:

{}.fetch(:nosuch, :default) 
{}.fetch(:nosuch) 

If key is not found and a block was given, yields key to the block and returns the block's return value:

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

Raises KeyError if neither default_value nor a block was given.

Note that this method does not use the values of either default or default_proc.

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];
        }
    }
}

fetch_values(*keys) → new_array click to toggle source

fetch_values(*keys) {|key| ... } → new_array

Returns a new Array containing the values associated with the given keys *keys:

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

Returns a new empty Array if no arguments given.

When a block is given, calls the block with each missing key, treating the block's return value as the value for that key:

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

When no block is given, raises an exception if any given key is not found.

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;
}

Hash#filter is an alias for Hash#select.

Returns a new Hash object whose entries are those for which the block returns a truthy value:

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

Returns a new Enumerator if no block given:

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

Hash#filter! is an alias for Hash#select!.

Returns self, whose entries are those for which the block returns a truthy value:

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

Returns nil if no entries were removed.

Returns a new Enumerator if no block given:

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

flatten → new_array click to toggle source

flatten(level) → new_array

Returns a new Array object that is a 1-dimensional flattening of self.

By default, nested Arrays are not flattened:

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

Takes the depth of recursive flattening from Integer argument level:

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

When level is negative, flattens all nested Arrays:

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

When level is zero, returns the equivalent of to_a :

h = {foo: 0, bar: [:bat, 3], baz: 2}
h.flatten(0) 
h.flatten(0) == h.to_a 
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;
}

has_key?(key) → true or false

Methods has_key?, key?, and member? are aliases for #include?.

Returns true if key is a key in self, otherwise false.

has_value?(value) → true or false click to toggle source

Returns true if value is a value in self, otherwise 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];
}

hash → an_integer click to toggle source

Returns the Integer hash-code for the hash.

Two Hash objects have the same hash-code if their content is the same (regardless or order):

h1 = {foo: 0, bar: 1, baz: 2}
h2 = {baz: 2, bar: 1, foo: 0}
h2.hash == h1.hash 
h2.eql? h1 
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);
}

include?(key) → true or false click to toggle source

Methods has_key?, key?, and member? are aliases for #include?.

Returns true if key is a key in self, otherwise false.

MJIT_FUNC_EXPORTED VALUE
rb_hash_has_key(VALUE hash, VALUE key)
{
    if (hash_stlike_lookup(hash, key, NULL)) {
        return Qtrue;
    }
    else {
        return Qfalse;
    }
}

Replaces the entire contents of self with the contents of other_hash; returns self:

h = {foo: 0, bar: 1, baz: 2}
h.replace({bat: 3, bam: 4}) 
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)) {
        if (RHASH_AR_TABLE_P(hash2)) {
            ar_clear(hash);
        }
        else {
            ar_free_and_clear_table(hash);
            RHASH_ST_TABLE_SET(hash, st_init_table_with_size(RHASH_TYPE(hash2), RHASH_SIZE(hash2)));
        }
    }
    else {
        if (RHASH_AR_TABLE_P(hash2)) {
            st_free_table(RHASH_ST_TABLE(hash));
            RHASH_ST_CLEAR(hash);
        }
        else {
            st_clear(RHASH_ST_TABLE(hash));
            RHASH_TBL_RAW(hash)->type = RHASH_ST_TABLE(hash2)->type;
        }
    }
    rb_hash_foreach(hash2, rb_hash_rehash_i, (VALUE)hash);

    rb_gc_writebarrier_remember(hash);

    return hash;
}

inspect → new_string click to toggle source

Returns a new String containing the hash entries:

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

Hash#to_s is an alias for Hash#inspect.

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);
}

invert → new_hash click to toggle source

Returns a new Hash object with the each key-value pair inverted:

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

Overwrites any repeated new keys: (see Entry Order):

h = {foo: 0, bar: 0, baz: 0}
h.invert 
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;
}

keep_if {|key, value| ... } → self click to toggle source

keep_if → new_enumerator

Calls the block for each key-value pair; retains the entry if the block returns a truthy value; otherwise deletes the entry; returns self.

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

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.keep_if 
e.each { |key, value| key.start_with?('b') } 
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;
}

key(value) → key or nil click to toggle source

Returns the key for the first-found entry with the given value (see Entry Order):

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

Returns nil if so such value is found.

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];
}

key?(key) → true or false

Methods has_key?, key?, and member? are aliases for #include?.

Returns true if key is a key in self, otherwise false.

keys → new_array click to toggle source

Returns a new Array containing all keys in self:

h = {foo: 0, bar: 1, baz: 2}
h.keys 
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;
}

length → integer

Returns the count of entries in self:

{foo: 0, bar: 1, baz: 2}.length 

Hash#length is an alias for Hash#size.

member?(key) → true or false

Methods has_key?, key?, and member? are aliases for #include?.

Returns true if key is a key in self, otherwise false.

merge → copy_of_self click to toggle source

merge(*other_hashes) → new_hash

merge(*other_hashes) { |key, old_value, new_value| ... } → new_hash

Returns the new Hash formed by merging each of other_hashes into a copy of self.

Each argument in other_hashes must be a Hash.

With arguments and no block:

Example:

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

With arguments and a block:

Example:

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 

With no arguments:

Example:

h = {foo: 0, bar: 1, baz: 2}
h.merge 
h1 = h.merge { |key, old_value, new_value| raise 'Cannot happen' }
h1 
static VALUE
rb_hash_merge(int argc, VALUE *argv, VALUE self)
{
    return rb_hash_update(argc, argv, rb_hash_dup(self));
}

merge! → self

merge!(*other_hashes) → self

merge!(*other_hashes) { |key, old_value, new_value| ... } → self

Merges each of other_hashes into self; returns self.

Each argument in other_hashes must be a Hash.

Method update is an alias for #merge!.

With arguments and no block:

Example:

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

With arguments and a block:

Example:

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 

With no arguments:

Example:

h = {foo: 0, bar: 1, baz: 2}
h.merge 
h1 = h.merge! { |key, old_value, new_value| raise 'Cannot happen' }
h1 

rassoc(value) → new_array or nil click to toggle source

Returns a new 2-element Array consisting of the key and value of the first-found entry whose value is == to value (see Entry Order):

h = {foo: 0, bar: 1, baz: 1}
h.rassoc(1) 

Returns nil if no such value found.

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];
}

rehash → self click to toggle source

Rebuilds the hash table by recomputing the hash index for each key; returns self.

The hash table becomes invalid if the hash value of a key has changed after the entry was created. See Modifying an Active Hash Key.

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;
}

reject {|key, value| ... } → new_hash click to toggle source

reject → new_enumerator

Returns a new Hash object whose entries are all those from self for which the block returns false or nil:

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

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.reject 
h1 = e.each {|key, value| key.start_with?('b') }
h1 
VALUE
rb_hash_reject(VALUE hash)
{
    VALUE result;

    RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    if (RTEST(ruby_verbose)) {
        VALUE klass;
        if (HAS_EXTRA_STATES(hash, klass)) {
            rb_warn("extra states are no longer copied: %+"PRIsVALUE, hash);
        }
    }
    result = rb_hash_new();
    if (!RHASH_EMPTY_P(hash)) {
        rb_hash_foreach(hash, reject_i, result);
    }
    return result;
}

reject! {|key, value| ... } → self or nil click to toggle source

reject! → new_enumerator

Returns self, whose remaining entries are those for which the block returns false or nil:

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

Returns nil if no entries are removed.

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.reject! 
e.each {|key, value| key.start_with?('b') } 
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;
}

replace(other_hash) → self

Replaces the entire contents of self with the contents of other_hash; returns self:

h = {foo: 0, bar: 1, baz: 2}
h.replace({bat: 3, bam: 4}) 

select {|key, value| ... } → new_hash click to toggle source

select → new_enumerator

Hash#filter is an alias for Hash#select.

Returns a new Hash object whose entries are those for which the block returns a truthy value:

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

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.select 
e.each {|key, value| value < 2 } 
static VALUE
rb_hash_select(VALUE hash)
{
    VALUE result;

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

select! {|key, value| ... } → self or nil click to toggle source

select! → new_enumerator

Hash#filter! is an alias for Hash#select!.

Returns self, whose entries are those for which the block returns a truthy value:

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

Returns nil if no entries were removed.

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.select!  
e.each { |key, value| value < 2 } 
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;
}

shift → [key, value] or default_value click to toggle source

Removes the first hash entry (see Entry Order); returns a 2-element Array containing the removed key and value:

h = {foo: 0, bar: 1, baz: 2}
h.shift 
h 

Returns the default value if the hash is empty (see Default Values).

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 (var.key != Qundef) {
                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 (var.key != Qundef) {
                rb_hash_delete_entry(hash, var.key);
                return rb_assoc_new(var.key, var.val);
            }
        }
    }
    return rb_hash_default_value(hash, Qnil);
}

size → integer click to toggle source

Returns the count of entries in self:

{foo: 0, bar: 1, baz: 2}.length 

Hash#length is an alias for Hash#size.

VALUE
rb_hash_size(VALUE hash)
{
    return INT2FIX(RHASH_SIZE(hash));
}

slice(*keys) → new_hash click to toggle source

Returns a new Hash object containing the entries for the given keys:

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

Any given keys that are not found are ignored.

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 rb_hash_new();
    }
    result = rb_hash_new_with_size(argc);

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

    return result;
}

store(key, value)

Hash#store is an alias for Hash#[]=.

Associates the given value with the given key; returns value.

If the given key exists, replaces its value with the given value; the ordering is not affected (see Entry Order):

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

If key does not exist, adds the key and value; the new entry is last in the order (see Entry Order):

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

to_a → new_array click to toggle source

Returns a new Array of 2-element Array objects; each nested Array contains a key-value pair from self:

h = {foo: 0, bar: 1, baz: 2}
h.to_a 
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;
}

to_h → self or new_hash click to toggle source

to_h {|key, value| ... } → new_hash

For an instance of Hash, returns self.

For a subclass of Hash, returns a new Hash containing the content of self.

When a block is given, returns a new Hash object whose content is based on the block; the block should return a 2-element Array object specifying the key-value pair to be included in the returned Array:

h = {foo: 0, bar: 1, baz: 2}
h1 = h.to_h {|key, value| [value, key] }
h1 
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;
}

to_hash → self click to toggle source

Returns self.

static VALUE
rb_hash_to_hash(VALUE hash)
{
    return hash;
}

to_proc → proc click to toggle source

Returns a Proc object that maps a key to its value:

h = {foo: 0, bar: 1, baz: 2}
proc = h.to_proc
proc.class 
proc.call(:foo) 
proc.call(:bar) 
proc.call(:nosuch) 
static VALUE
rb_hash_to_proc(VALUE hash)
{
    return rb_func_lambda_new(hash_proc_call, hash, 1, 1);
}

Returns a new String containing the hash entries:

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

Hash#to_s is an alias for Hash#inspect.

transform_keys {|key| ... } → new_hash click to toggle source

transform_keys(hash2) → new_hash

transform_keys(hash2) {|other_key| ...} → new_hash

transform_keys → new_enumerator

Returns a new Hash object; each entry has:

An optional hash argument can be provided to map keys to new keys. Any key not given will be mapped using the provided block, or remain the same if no block is given.

Transform keys:

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

h.transform_keys(foo: :bar, bar: :foo)


h.transform_keys(foo: :hello, &:to_s)

Overwrites values for duplicate keys:

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

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.transform_keys 
h1 = e.each { |key| key.to_s }
h1 
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;
}

transform_keys! {|key| ... } → self click to toggle source

transform_keys!(hash2) → self

transform_keys!(hash2) {|other_key| ...} → self

transform_keys! → new_enumerator

Same as Hash#transform_keys but modifies the receiver in place instead of returning a new hash.

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_tmp_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 ((new_key = rb_hash_lookup2(trans, key, Qundef)) != 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;
}

transform_values {|value| ... } → new_hash click to toggle source

transform_values → new_enumerator

Returns a new Hash object; each entry has:

Transform values:

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

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.transform_values 
h1 = e.each { |value| value * 100}
h1 
static VALUE
rb_hash_transform_values(VALUE hash)
{
    VALUE result;

    RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    result = hash_copy(hash_alloc(rb_cHash), 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;
}

transform_values! {|value| ... } → self click to toggle source

transform_values! → new_enumerator

Returns self, whose keys are unchanged, and whose values are determined by the given block.

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

Returns a new Enumerator if no block given:

h = {foo: 0, bar: 1, baz: 2}
e = h.transform_values! 
h1 = e.each {|value| value * 100}
h1 
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;
}

Merges each of other_hashes into self; returns self.

Each argument in other_hashes must be a Hash.

Method update is an alias for #merge!.

With arguments and no block:

Example:

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

With arguments and a block:

Example:

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 

With no arguments:

Example:

h = {foo: 0, bar: 1, baz: 2}
h.merge 
h1 = h.merge! { |key, old_value, new_value| raise 'Cannot happen' }
h1 
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;
}

Returns true if value is a value in self, otherwise false.

values → new_array click to toggle source

Returns a new Array containing all values in self:

h = {foo: 0, bar: 1, baz: 2}
h.values 
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;
}

values_at(*keys) → new_array click to toggle source

Returns a new Array containing values for the given keys:

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

The default values are returned for any keys that are not found:

h.values_at(:hello, :foo) 
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;
}

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4