Class: Hash

Inherits:
Object show all
Includes:
Enumerable
Defined in:
hash.c

Overview

A Hash is a dictionary-like collection of unique keys and their values. Also called associative arrays, they are similar to Arrays, but where an Array uses integers as its index, a Hash allows you to use any object type.

Hashes enumerate their values in the order that the corresponding keys were inserted.

A Hash can be easily created by using its implicit form:

grades = { "Jane Doe" => 10, "Jim Doe" => 6 }

Hashes allow an alternate syntax form when your keys are always symbols. Instead of

options = { :font_size => 10, :font_family => "Arial" }

You could write it as:

options = { font_size: 10, font_family: "Arial" }

Each named key is a symbol you can access in hash:

options[:font_size]  # => 10

A Hash can also be created through its ::new method:

grades = Hash.new
grades["Dorothy Doe"] = 9

Hashes have a default value that is returned when accessing keys that do not exist in the hash. If no default is set nil is used. You can set the default value by sending it as an argument to Hash.new:

grades = Hash.new(0)

Or by using the #default= method:

grades = {"Timmy Doe" => 8}
grades.default = 0

Accessing a value in a Hash requires using its key:

puts grades["Jane Doe"] # => 0

Common Uses

Hashes are an easy way to represent data structures, such as

books         = {}
books[:matz]  = "The Ruby Language"
books[:black] = "The Well-Grounded Rubyist"

Hashes are also commonly used as a way to have named parameters in functions. Note that no brackets are used below. If a hash is the last argument on a method call, no braces are needed, thus creating a really clean interface:

Person.create(name: "John Doe", age: 27)

def self.create(params)
  @name = params[:name]
  @age  = params[:age]
end

Hash Keys

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

A user-defined class may be used as a hash key if the hash and eql? methods are overridden to provide meaningful behavior. By default, separate instances refer to separate hash keys.

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 and
      other.author == @author and
      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

See also Object#hash and Object#eql?

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Enumerable

#all?, #any?, #chunk, #collect, #collect_concat, #count, #cycle, #detect, #drop, #drop_while, #each_cons, #each_entry, #each_slice, #each_with_index, #each_with_object, #entries, #find, #find_all, #find_index, #first, #flat_map, #grep, #group_by, #inject, #lazy, #map, #max, #max_by, #min, #min_by, #minmax, #minmax_by, #none?, #one?, #partition, #reduce, #reverse_each, #slice_before, #sort, #sort_by, #take, #take_while, #zip

Constructor Details

#newObject #new(obj) ⇒ Object #new {|hash, key| ... } ⇒ Object

Returns a new, empty hash. If this hash is subsequently accessed by a key that doesn’t correspond to a hash entry, the value returned depends on the style of new used to create the hash. In the first form, the access returns nil. If obj is specified, this single object will be used for all default values. If a block is specified, it will be called with the hash object and the key, and should return the default value. It is the block’s responsibility to store the value in the hash if required.

h = Hash.new("Go Fish")
h["a"] = 100
h["b"] = 200
h["a"]           #=> 100
h["c"]           #=> "Go Fish"
# The following alters the single default object
h["c"].upcase!   #=> "GO FISH"
h["d"]           #=> "GO FISH"
h.keys           #=> ["a", "b"]

# While this creates a new default object each time
h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }
h["c"]           #=> "Go Fish: c"
h["c"].upcase!   #=> "GO FISH: C"
h["d"]           #=> "Go Fish: d"
h.keys           #=> ["c", "d"]

Overloads:



475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
# File 'hash.c', line 475

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();
	default_proc_arity_check(ifnone);
	RHASH_SET_IFNONE(hash, ifnone);
	FL_SET(hash, HASH_PROC_DEFAULT);
    }
    else {
	rb_scan_args(argc, argv, "01", &ifnone);
	RHASH_SET_IFNONE(hash, ifnone);
    }

    return hash;
}

Class Method Details

.[](key, value, ...) ⇒ Object .[]([ [key, value)) ⇒ Object .[](object) ⇒ Object

Creates a new hash populated with the given objects.

Similar to the literal { key => value, ... }. In the first form, keys and values occur in pairs, so there must be an even number of arguments.

The second and third form take a single argument which is either an array of key-value pairs or an object convertible to a hash.

Hash["a", 100, "b", 200]             #=> {"a"=>100, "b"=>200}
Hash[ [ ["a", 100], ["b", 200] ] ]   #=> {"a"=>100, "b"=>200}
Hash["a" => 100, "b" => 200]         #=> {"a"=>100, "b"=>200}


516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
# File 'hash.c', line 516

static VALUE
rb_hash_s_create(int argc, VALUE *argv, VALUE klass)
{
    VALUE hash, tmp;
    int i;

    if (argc == 1) {
	tmp = rb_hash_s_try_convert(Qnil, argv[0]);
	if (!NIL_P(tmp)) {
	    hash = hash_alloc(klass);
	    if (RHASH(tmp)->ntbl) {
		RHASH(hash)->ntbl = st_copy(RHASH(tmp)->ntbl);
	    }
	    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)) {
#if 0 /* refix in the next release */
		    rb_raise(rb_eArgError, "wrong element type %s at %ld (expected array)",
			     rb_builtin_class_name(e), i);

#else
		    rb_warn("wrong element type %s at %ld (expected array)",
			    rb_builtin_class_name(e), i);
		    rb_warn("ignoring wrong elements is deprecated, remove them explicitly");
		    rb_warn("this causes ArgumentError in the next release");
		    continue;
#endif
		}
		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);
    for (i=0; i<argc; i+=2) {
        rb_hash_aset(hash, argv[i], argv[i + 1]);
    }

    return hash;
}

.try_convert(obj) ⇒ Hash?

Try to convert obj into a hash, using to_hash method. Returns converted hash or nil if obj cannot be converted for any reason.

Hash.try_convert({1=>2})   # => {1=>2}
Hash.try_convert("1=>2")   # => nil

Returns:



604
605
606
607
608
# File 'hash.c', line 604

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

Instance Method Details

#==(other_hash) ⇒ Boolean

Equality—Two hashes are equal if they each contain the same number of keys and if each key-value pair is equal to (according to Object#==) the corresponding elements in the other hash.

h1 = { "a" => 1, "c" => 2 }
h2 = { 7 => 35, "c" => 2, "a" => 1 }
h3 = { "a" => 1, "c" => 2, 7 => 35 }
h4 = { "a" => 1, "d" => 2, "f" => 35 }
h1 == h2   #=> false
h2 == h3   #=> true
h3 == h4   #=> false

Returns:

  • (Boolean)


2000
2001
2002
2003
2004
# File 'hash.c', line 2000

static VALUE
rb_hash_equal(VALUE hash1, VALUE hash2)
{
    return hash_equal(hash1, hash2, FALSE);
}

#[](key) ⇒ Object

Element Reference—Retrieves the value object corresponding to the key object. If not found, returns the default value (see Hash::new for details).

h = { "a" => 100, "b" => 200 }
h["a"]   #=> 100
h["c"]   #=> nil


696
697
698
699
700
701
702
703
704
705
# File 'hash.c', line 696

VALUE
rb_hash_aref(VALUE hash, VALUE key)
{
    st_data_t val;

    if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
	return hash_default_value(hash, key);
    }
    return (VALUE)val;
}

#[]=(key) ⇒ Object #store(key, value) ⇒ Object

Element Assignment

Associates the value given by value with the key given by key.

h = { "a" => 100, "b" => 200 }
h["a"] = 9
h["c"] = 4
h   #=> {"a"=>9, "b"=>200, "c"=>4}
h.store("d", 42) #=> {"a"=>9, "b"=>200, "c"=>4, "d"=>42}

key should not have its value changed while it is in use as a key (an unfrozen String passed as a key will be duplicated and frozen).

a = "a"
b = "b".freeze
h = { a => 100, b => 200 }
h.key(100).equal? a #=> false
h.key(200).equal? b #=> true


1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
# File 'hash.c', line 1392

VALUE
rb_hash_aset(VALUE hash, VALUE key, VALUE val)
{
    int iter_lev = RHASH_ITER_LEV(hash);
    st_table *tbl = RHASH(hash)->ntbl;

    rb_hash_modify(hash);
    if (!tbl) {
	if (iter_lev > 0) no_new_key();
	tbl = hash_tbl(hash);
    }
    if (tbl->type == &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;
}

#assoc(obj) ⇒ Array?

Searches through the hash comparing obj with the key using ==. Returns the key-value pair (two elements array) or nil if no match is found. See Array#assoc.

h = {"colors"  => ["red", "blue", "green"],
     "letters" => ["a", "b", "c" ]}
h.assoc("letters")  #=> ["letters", ["a", "b", "c"]]
h.assoc("foo")      #=> nil

Returns:



2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
# File 'hash.c', line 2302

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;
    table = RHASH(hash)->ntbl;
    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];
}

#clearHash

Removes all key-value pairs from hsh.

h = { "a" => 100, "b" => 200 }   #=> {"a"=>100, "b"=>200}
h.clear                          #=> {}

Returns:



1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
# File 'hash.c', line 1323

VALUE
rb_hash_clear(VALUE hash)
{
    rb_hash_modify_check(hash);
    if (!RHASH(hash)->ntbl)
        return hash;
    if (RHASH(hash)->ntbl->num_entries > 0) {
	if (RHASH_ITER_LEV(hash) > 0)
	    rb_hash_foreach(hash, clear_i, 0);
	else
	    st_clear(RHASH(hash)->ntbl);
    }

    return hash;
}

#compare_by_identityHash

Makes hsh compare its keys by their identity, i.e. it will consider exact same objects as same keys.

h1 = { "a" => 100, "b" => 200, :c => "c" }
h1["a"]        #=> 100
h1.compare_by_identity
h1.compare_by_identity? #=> true
h1["a"]        #=> nil  # different objects.
h1[:c]         #=> "c"  # same symbols are all same.

Returns:



2444
2445
2446
2447
2448
2449
2450
2451
2452
# File 'hash.c', line 2444

static VALUE
rb_hash_compare_by_id(VALUE hash)
{
    if (rb_hash_compare_by_id_p(hash)) return hash;
    rb_hash_modify(hash);
    RHASH(hash)->ntbl->type = &identhash;
    rb_hash_rehash(hash);
    return hash;
}

#compare_by_identity?Boolean

Returns true if hsh will compare its keys by their identity. Also see Hash#compare_by_identity.

Returns:

  • (Boolean)

Returns:

  • (Boolean)


2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
# File 'hash.c', line 2463

static VALUE
rb_hash_compare_by_id_p(VALUE hash)
{
    if (!RHASH(hash)->ntbl)
        return Qfalse;
    if (RHASH(hash)->ntbl->type == &identhash) {
	return Qtrue;
    }
    return Qfalse;
}

#default(key = nil) ⇒ Object

Returns the default value, the value that would be returned by hsh[key] if key did not exist in hsh. See also Hash::new and Hash#default=.

h = Hash.new                            #=> {}
h.default                               #=> nil
h.default(2)                            #=> nil

h = Hash.new("cat")                     #=> {}
h.default                               #=> "cat"
h.default(2)                            #=> "cat"

h = Hash.new {|h,k| h[k] = k.to_i*10}   #=> {}
h.default                               #=> nil
h.default(2)                            #=> 20

Returns:



808
809
810
811
812
813
814
815
816
817
818
819
820
# File 'hash.c', line 808

static VALUE
rb_hash_default(int argc, VALUE *argv, VALUE hash)
{
    VALUE key, ifnone;

    rb_scan_args(argc, argv, "01", &key);
    ifnone = RHASH_IFNONE(hash);
    if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
	if (argc == 0) return Qnil;
	return rb_funcall(ifnone, id_yield, 2, hash, key);
    }
    return ifnone;
}

#default=(obj) ⇒ Object

Sets the default value, the value returned for a key that does not exist in the hash. It is not possible to set the default to a Proc that will be executed on each key lookup.

h = { "a" => 100, "b" => 200 }
h.default = "Go fish"
h["a"]     #=> 100
h["z"]     #=> "Go fish"
# This doesn't do what you might hope...
h.default = proc do |hash, key|
  hash[key] = key + key
end
h[2]       #=> #<Proc:0x401b3948@-:6>
h["cat"]   #=> #<Proc:0x401b3948@-:6>

Returns:



842
843
844
845
846
847
848
849
# File 'hash.c', line 842

static VALUE
rb_hash_set_default(VALUE hash, VALUE ifnone)
{
    rb_hash_modify_check(hash);
    RHASH_SET_IFNONE(hash, ifnone);
    FL_UNSET(hash, HASH_PROC_DEFAULT);
    return ifnone;
}

#default_procObject

If Hash::new was invoked with a block, return that block, otherwise return nil.

h = Hash.new {|h,k| h[k] = k*k }   #=> {}
p = h.default_proc                 #=> #<Proc:0x401b3d08@-:1>
a = []                             #=> []
p.call(a, 2)
a                                  #=> [nil, nil, 4]

Returns:



866
867
868
869
870
871
872
873
# File 'hash.c', line 866

static VALUE
rb_hash_default_proc(VALUE hash)
{
    if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
	return RHASH_IFNONE(hash);
    }
    return Qnil;
}

#default_proc=(proc_obj) ⇒ Object

Sets the default proc to be executed on each failed key lookup.

h.default_proc = proc do |hash, key|
  hash[key] = key + key
end
h[2]       #=> 4
h["cat"]   #=> "catcat"


888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
# File 'hash.c', line 888

static VALUE
rb_hash_set_default_proc(VALUE hash, VALUE proc)
{
    VALUE b;

    rb_hash_modify_check(hash);
    if (NIL_P(proc)) {
	FL_UNSET(hash, HASH_PROC_DEFAULT);
	RHASH_SET_IFNONE(hash, proc);
	return proc;
    }
    b = rb_check_convert_type(proc, T_DATA, "Proc", "to_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;
    default_proc_arity_check(proc);
    RHASH_SET_IFNONE(hash, proc);
    FL_SET(hash, HASH_PROC_DEFAULT);
    return proc;
}

#delete(key) ⇒ Object #delete(key) {|key| ... } ⇒ Object

Deletes the key-value pair and returns the value from hsh whose key is equal to key. If the key is not found, returns the default value. If the optional code block is given and the key is not found, pass in the key and return the result of block.

h = { "a" => 100, "b" => 200 }
h.delete("a")                              #=> 100
h.delete("z")                              #=> nil
h.delete("z") { |el| "#{el} not found" }   #=> "z not found"

Overloads:

  • #delete(key) {|key| ... } ⇒ Object

    Yields:



995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
# File 'hash.c', line 995

VALUE
rb_hash_delete(VALUE hash, VALUE key)
{
    VALUE val;

    rb_hash_modify_check(hash);
    val = rb_hash_delete_key(hash, key);
    if (val != Qundef) return val;
    if (rb_block_given_p()) {
	return rb_yield(key);
    }
    return Qnil;
}

#delete_if {|key, value| ... } ⇒ Hash #delete_ifObject

Deletes every key-value pair from hsh for which block evaluates to true.

If no block is given, an enumerator is returned instead.

h = { "a" => 100, "b" => 200, "c" => 300 }
h.delete_if {|key, value| key >= "b" }   #=> {"a"=>100}

Overloads:

  • #delete_if {|key, value| ... } ⇒ Hash

    Yields:

    Returns:



1093
1094
1095
1096
1097
1098
1099
1100
1101
# File 'hash.c', line 1093

VALUE
rb_hash_delete_if(VALUE hash)
{
    RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    rb_hash_modify_check(hash);
    if (RHASH(hash)->ntbl)
	rb_hash_foreach(hash, delete_if_i, hash);
    return hash;
}

#each {|key, value| ... } ⇒ Hash #each_pair {|key, value| ... } ⇒ Hash #eachObject #each_pairObject

Calls block once for each key in hsh, passing the key-value pair as parameters.

If no block is given, an enumerator is returned instead.

h = { "a" => 100, "b" => 200 }
h.each {|key, value| puts "#{key} is #{value}" }

produces:

a is 100
b is 200

Overloads:

  • #each {|key, value| ... } ⇒ Hash

    Yields:

    Returns:

  • #each_pair {|key, value| ... } ⇒ Hash

    Yields:

    Returns:



1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
# File 'hash.c', line 1630

static VALUE
rb_hash_each_pair(VALUE hash)
{
    RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    if (rb_block_arity() > 1)
	rb_hash_foreach(hash, each_pair_i_fast, 0);
    else
	rb_hash_foreach(hash, each_pair_i, 0);
    return hash;
}

#each_key {|key| ... } ⇒ Hash #each_keyObject

Calls block once for each key in hsh, passing the key as a parameter.

If no block is given, an enumerator is returned instead.

h = { "a" => 100, "b" => 200 }
h.each_key {|key| puts key }

produces:

a
b

Overloads:

  • #each_key {|key| ... } ⇒ Hash

    Yields:

    Returns:



1586
1587
1588
1589
1590
1591
1592
# File 'hash.c', line 1586

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

#each {|key, value| ... } ⇒ Hash #each_pair {|key, value| ... } ⇒ Hash #eachObject #each_pairObject

Calls block once for each key in hsh, passing the key-value pair as parameters.

If no block is given, an enumerator is returned instead.

h = { "a" => 100, "b" => 200 }
h.each {|key, value| puts "#{key} is #{value}" }

produces:

a is 100
b is 200

Overloads:

  • #each {|key, value| ... } ⇒ Hash

    Yields:

    Returns:

  • #each_pair {|key, value| ... } ⇒ Hash

    Yields:

    Returns:



1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
# File 'hash.c', line 1630

static VALUE
rb_hash_each_pair(VALUE hash)
{
    RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    if (rb_block_arity() > 1)
	rb_hash_foreach(hash, each_pair_i_fast, 0);
    else
	rb_hash_foreach(hash, each_pair_i, 0);
    return hash;
}

#each_value {|value| ... } ⇒ Hash #each_valueObject

Calls block once for each key in hsh, passing the value as a parameter.

If no block is given, an enumerator is returned instead.

h = { "a" => 100, "b" => 200 }
h.each_value {|value| puts value }

produces:

100
200

Overloads:

  • #each_value {|value| ... } ⇒ Hash

    Yields:

    • (value)

    Returns:



1553
1554
1555
1556
1557
1558
1559
# File 'hash.c', line 1553

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?Boolean

Returns true if hsh contains no key-value pairs.

{}.empty?   #=> true

Returns:

  • (Boolean)

Returns:

  • (Boolean)


1521
1522
1523
1524
1525
# File 'hash.c', line 1521

static VALUE
rb_hash_empty_p(VALUE hash)
{
    return RHASH_EMPTY_P(hash) ? Qtrue : Qfalse;
}

#eql?(other) ⇒ Boolean

Returns true if hash and other are both hashes with the same content.

Returns:

  • (Boolean)

Returns:

  • (Boolean)


2014
2015
2016
2017
2018
# File 'hash.c', line 2014

static VALUE
rb_hash_eql(VALUE hash1, VALUE hash2)
{
    return hash_equal(hash1, hash2, TRUE);
}

#fetch(key[, default]) ⇒ Object #fetch(key) {|key| ... } ⇒ Object

Returns a value from the hash for the given key. If the key can’t be found, there are several options: With no other arguments, it will raise an KeyError exception; if default is given, then that will be returned; if the optional code block is specified, then that will be run and its result returned.

h = { "a" => 100, "b" => 200 }
h.fetch("a")                            #=> 100
h.fetch("z", "go fish")                 #=> "go fish"
h.fetch("z") { |el| "go fish, #{el}"}   #=> "go fish, z"

The following example shows that an exception is raised if the key is not found and a default value is not supplied.

h = { "a" => 100, "b" => 200 }
h.fetch("z")

produces:

prog.rb:2:in `fetch': key not found (KeyError)
 from prog.rb:2

Overloads:



753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
# File 'hash.c', line 753

static VALUE
rb_hash_fetch_m(int argc, VALUE *argv, VALUE hash)
{
    VALUE key, if_none;
    st_data_t val;
    long block_given;

    rb_scan_args(argc, argv, "11", &key, &if_none);

    block_given = rb_block_given_p();
    if (block_given && argc == 2) {
	rb_warn("block supersedes default value argument");
    }
    if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
	if (block_given) return rb_yield(key);
	if (argc == 1) {
	    volatile 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_raise(rb_eKeyError, "key not found: %"PRIsVALUE, desc);
	}
	return if_none;
    }
    return (VALUE)val;
}

#flattenArray #flatten(level) ⇒ Array

Returns a new array that is a one-dimensional flattening of this hash. That is, for every key or value that is an array, extract its elements into the new array. Unlike Array#flatten, this method does not flatten recursively by default. The optional level argument determines the level of recursion to flatten.

a =  {1=> "one", 2 => [2,"two"], 3 => "three"}
a.flatten    # => [1, "one", 2, [2, "two"], 3, "three"]
a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"]

Overloads:



2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
# File 'hash.c', line 2399

static VALUE
rb_hash_flatten(int argc, VALUE *argv, VALUE hash)
{
    VALUE ary;

    if (argc) {
	int level = NUM2INT(*argv);
	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);
	if (level - 1 > 0) {
	    *argv = INT2FIX(level - 1);
	    rb_funcall2(ary, id_flatten_bang, argc, argv);
	}
	else if (level < 0) {
	    rb_funcall2(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) ⇒ Boolean #include?(key) ⇒ Boolean #key?(key) ⇒ Boolean #member?(key) ⇒ Boolean

Returns true if the given key is present in hsh.

h = { "a" => 100, "b" => 200 }
h.has_key?("a")   #=> true
h.has_key?("z")   #=> false

Overloads:

  • #has_key?(key) ⇒ Boolean

    Returns:

    • (Boolean)
  • #include?(key) ⇒ Boolean

    Returns:

    • (Boolean)
  • #key?(key) ⇒ Boolean

    Returns:

    • (Boolean)
  • #member?(key) ⇒ Boolean

    Returns:

    • (Boolean)

Returns:

  • (Boolean)


1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
# File 'hash.c', line 1866

static VALUE
rb_hash_has_key(VALUE hash, VALUE key)
{
    if (!RHASH(hash)->ntbl)
        return Qfalse;
    if (st_lookup(RHASH(hash)->ntbl, key, 0)) {
	return Qtrue;
    }
    return Qfalse;
}

#has_value?(value) ⇒ Boolean #value?(value) ⇒ Boolean

Returns true if the given value is present for some key in hsh.

h = { "a" => 100, "b" => 200 }
h.has_value?(100)   #=> true
h.has_value?(999)   #=> false

Overloads:

  • #has_value?(value) ⇒ Boolean

    Returns:

    • (Boolean)
  • #value?(value) ⇒ Boolean

    Returns:

    • (Boolean)

Returns:

  • (Boolean)


1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
# File 'hash.c', line 1902

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

#hashFixnum

Compute a hash-code for this hash. Two hashes with the same content will have the same hash code (and will compare using eql?).

Returns:



2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
# File 'hash.c', line 2040

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 INT2FIX(hval);
}

#has_key?(key) ⇒ Boolean #include?(key) ⇒ Boolean #key?(key) ⇒ Boolean #member?(key) ⇒ Boolean

Returns true if the given key is present in hsh.

h = { "a" => 100, "b" => 200 }
h.has_key?("a")   #=> true
h.has_key?("z")   #=> false

Overloads:

  • #has_key?(key) ⇒ Boolean

    Returns:

    • (Boolean)
  • #include?(key) ⇒ Boolean

    Returns:

    • (Boolean)
  • #key?(key) ⇒ Boolean

    Returns:

    • (Boolean)
  • #member?(key) ⇒ Boolean

    Returns:

    • (Boolean)

Returns:

  • (Boolean)


1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
# File 'hash.c', line 1866

static VALUE
rb_hash_has_key(VALUE hash, VALUE key)
{
    if (!RHASH(hash)->ntbl)
        return Qfalse;
    if (st_lookup(RHASH(hash)->ntbl, key, 0)) {
	return Qtrue;
    }
    return Qfalse;
}

#indexObject

:nodoc:



952
953
954
955
956
957
# File 'hash.c', line 952

static VALUE
rb_hash_index(VALUE hash, VALUE value)
{
    rb_warn("Hash#index is deprecated; use Hash#key");
    return rb_hash_key(hash, value);
}

#initialize_copyObject

:nodoc:



1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
# File 'hash.c', line 1421

static VALUE
rb_hash_initialize_copy(VALUE hash, VALUE hash2)
{
    st_table *ntbl;

    rb_hash_modify_check(hash);
    hash2 = to_hash(hash2);

    Check_Type(hash2, T_HASH);

    if (hash == hash2) return hash;

    ntbl = RHASH(hash)->ntbl;
    if (RHASH(hash2)->ntbl) {
	if (ntbl) st_free_table(ntbl);
        RHASH(hash)->ntbl = st_copy(RHASH(hash2)->ntbl);
	if (RHASH(hash)->ntbl->num_entries)
	    rb_hash_rehash(hash);
    }
    else if (ntbl) {
	st_clear(ntbl);
    }

    if (FL_TEST(hash2, HASH_PROC_DEFAULT)) {
        FL_SET(hash, HASH_PROC_DEFAULT);
    }
    else {
	FL_UNSET(hash, HASH_PROC_DEFAULT);
    }
    RHASH_SET_IFNONE(hash, RHASH_IFNONE(hash2));

    return hash;
}

#to_sString #inspectString Also known as: to_s

Return the contents of this hash as a string.

h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  }
h.to_s   #=> "{\"c\"=>300, \"a\"=>100, \"d\"=>400}"

Overloads:



1718
1719
1720
1721
1722
1723
1724
# File 'hash.c', line 1718

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

#invertObject

Returns a new hash created by using hsh’s values as keys, and the keys as values.

h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 }
h.invert   #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"}


2072
2073
2074
2075
2076
2077
2078
2079
# File 'hash.c', line 2072

static VALUE
rb_hash_invert(VALUE hash)
{
    VALUE h = rb_hash_new();

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

#keep_if {|key, value| ... } ⇒ Hash #keep_ifObject

Deletes every key-value pair from hsh for which block evaluates to false.

If no block is given, an enumerator is returned instead.

Overloads:

  • #keep_if {|key, value| ... } ⇒ Hash

    Yields:

    Returns:



1296
1297
1298
1299
1300
1301
1302
1303
1304
# File 'hash.c', line 1296

VALUE
rb_hash_keep_if(VALUE hash)
{
    RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
    rb_hash_modify_check(hash);
    if (RHASH(hash)->ntbl)
	rb_hash_foreach(hash, keep_if_i, hash);
    return hash;
}

#key(value) ⇒ Object

Returns the key of an occurrence of a given value. If the value is not found, returns nil.

h = { "a" => 100, "b" => 200, "c" => 300, "d" => 300 }
h.key(200)   #=> "b"
h.key(300)   #=> "c"
h.key(999)   #=> nil


938
939
940
941
942
943
944
945
946
947
948
949
# File 'hash.c', line 938

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

#has_key?(key) ⇒ Boolean #include?(key) ⇒ Boolean #key?(key) ⇒ Boolean #member?(key) ⇒ Boolean

Returns true if the given key is present in hsh.

h = { "a" => 100, "b" => 200 }
h.has_key?("a")   #=> true
h.has_key?("z")   #=> false

Overloads:

  • #has_key?(key) ⇒ Boolean

    Returns:

    • (Boolean)
  • #include?(key) ⇒ Boolean

    Returns:

    • (Boolean)
  • #key?(key) ⇒ Boolean

    Returns:

    • (Boolean)
  • #member?(key) ⇒ Boolean

    Returns:

    • (Boolean)

Returns:

  • (Boolean)


1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
# File 'hash.c', line 1866

static VALUE
rb_hash_has_key(VALUE hash, VALUE key)
{
    if (!RHASH(hash)->ntbl)
        return Qfalse;
    if (st_lookup(RHASH(hash)->ntbl, key, 0)) {
	return Qtrue;
    }
    return Qfalse;
}

#keysArray

Returns a new array populated with the keys from this hash. See also Hash#values.

h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 }
h.keys   #=> ["a", "b", "c", "d"]

Returns:



1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
# File 'hash.c', line 1782

VALUE
rb_hash_keys(VALUE hash)
{
    VALUE keys;
    st_index_t size = RHASH_SIZE(hash);

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

    if (ST_DATA_COMPATIBLE_P(VALUE)) {
	st_table *table = RHASH(hash)->ntbl;

	if (OBJ_PROMOTED(keys)) rb_gc_writebarrier_remember_promoted(keys);
	RARRAY_PTR_USE(keys, ptr, {
	    size = st_keys_check(table, ptr, size, Qundef);
	});
	rb_ary_set_len(keys, size);
    }
    else {
	rb_hash_foreach(hash, keys_i, keys);
    }

    return keys;
}

#lengthFixnum #sizeFixnum

Returns the number of key-value pairs in the hash.

h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
h.length        #=> 4
h.delete("a")   #=> 200
h.length        #=> 3

Overloads:



1504
1505
1506
1507
1508
# File 'hash.c', line 1504

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

#has_key?(key) ⇒ Boolean #include?(key) ⇒ Boolean #key?(key) ⇒ Boolean #member?(key) ⇒ Boolean

Returns true if the given key is present in hsh.

h = { "a" => 100, "b" => 200 }
h.has_key?("a")   #=> true
h.has_key?("z")   #=> false

Overloads:

  • #has_key?(key) ⇒ Boolean

    Returns:

    • (Boolean)
  • #include?(key) ⇒ Boolean

    Returns:

    • (Boolean)
  • #key?(key) ⇒ Boolean

    Returns:

    • (Boolean)
  • #member?(key) ⇒ Boolean

    Returns:

    • (Boolean)

Returns:

  • (Boolean)


1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
# File 'hash.c', line 1866

static VALUE
rb_hash_has_key(VALUE hash, VALUE key)
{
    if (!RHASH(hash)->ntbl)
        return Qfalse;
    if (st_lookup(RHASH(hash)->ntbl, key, 0)) {
	return Qtrue;
    }
    return Qfalse;
}

#merge(other_hash) ⇒ Object #merge(other_hash) {|key, oldval, newval| ... } ⇒ Object

Returns a new hash containing the contents of other_hash and the contents of hsh. If no block is specified, the value for entries with duplicate keys will be that of other_hash. Otherwise the value for each duplicate key is determined by calling the block with the key, its value in hsh and its value in other_hash.

h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h1.merge(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}
h1.merge(h2){|key, oldval, newval| newval - oldval}
               #=> {"a"=>100, "b"=>54,  "c"=>300}
h1             #=> {"a"=>100, "b"=>200}

Overloads:

  • #merge(other_hash) {|key, oldval, newval| ... } ⇒ Object

    Yields:

    • (key, oldval, newval)


2244
2245
2246
2247
2248
# File 'hash.c', line 2244

static VALUE
rb_hash_merge(VALUE hash1, VALUE hash2)
{
    return rb_hash_update(rb_obj_dup(hash1), hash2);
}

#merge!(other_hash) ⇒ Hash #update(other_hash) ⇒ Hash #merge!(other_hash) {|key, oldval, newval| ... } ⇒ Hash #update(other_hash) {|key, oldval, newval| ... } ⇒ Hash

Adds the contents of other_hash to hsh. If no block is specified, entries with duplicate keys are overwritten with the values from other_hash, otherwise the value of each duplicate key is determined by calling the block with the key, its value in hsh and its value in other_hash.

h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h1.merge!(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}

h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h1.merge!(h2) { |key, v1, v2| v1 }
                #=> {"a"=>100, "b"=>200, "c"=>300}

Overloads:

  • #merge!(other_hash) ⇒ Hash

    Returns:

  • #update(other_hash) ⇒ Hash

    Returns:

  • #merge!(other_hash) {|key, oldval, newval| ... } ⇒ Hash

    Yields:

    • (key, oldval, newval)

    Returns:

  • #update(other_hash) {|key, oldval, newval| ... } ⇒ Hash

    Yields:

    • (key, oldval, newval)

    Returns:



2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
# File 'hash.c', line 2155

static VALUE
rb_hash_update(VALUE hash1, VALUE hash2)
{
    rb_hash_modify(hash1);
    hash2 = to_hash(hash2);
    if (rb_block_given_p()) {
	rb_hash_foreach(hash2, rb_hash_update_block_i, hash1);
    }
    else {
	rb_hash_foreach(hash2, rb_hash_update_i, hash1);
    }
    return hash1;
}

#rassoc(obj) ⇒ Array?

Searches through the hash comparing obj with the value using ==. Returns the first key-value pair (two-element array) that matches. See also Array#rassoc.

a = {1=> "one", 2 => "two", 3 => "three", "ii" => "two"}
a.rassoc("two")    #=> [2, "two"]
a.rassoc("four")   #=> nil

Returns:



2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
# File 'hash.c', line 2360

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

#rehashHash

Rebuilds the hash based on the current hash values for each key. If values of key objects have changed since they were inserted, this method will reindex hsh. If Hash#rehash is called while an iterator is traversing the hash, an RuntimeError will be raised in the iterator.

a = [ "a", "b" ]
c = [ "c", "d" ]
h = { a => 100, c => 300 }
h[a]       #=> 100
a[0] = "z"
h[a]       #=> nil
h.rehash   #=> {["z", "b"]=>100, ["c", "d"]=>300}
h[a]       #=> 100

Returns:



644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
# File 'hash.c', line 644

static 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(hash)->ntbl)
        return hash;
    tmp = hash_alloc(0);
    tbl = st_init_table_with_size(RHASH(hash)->ntbl->type, RHASH(hash)->ntbl->num_entries);
    RHASH(tmp)->ntbl = tbl;

    rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tbl);
    st_free_table(RHASH(hash)->ntbl);
    RHASH(hash)->ntbl = tbl;
    RHASH(tmp)->ntbl = 0;

    return hash;
}

#reject {|key, value| ... } ⇒ Hash #rejectObject

Returns a new hash consisting of entries for which the block returns false.

If no block is given, an enumerator is returned instead.

h = { "a" => 100, "b" => 200, "c" => 300 }
h.reject {|k,v| k < "b"}  #=> {"b" => 200, "c" => 300}
h.reject {|k,v| v > 100}  #=> {"a" => 100}

Overloads:

  • #reject {|key, value| ... } ⇒ Hash

    Yields:

    Returns:



1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
# File 'hash.c', line 1149

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)) {
#if HASH_REJECT_COPY_EXTRA_STATES
	    rb_warn("copying extra states: %+"PRIsVALUE, hash);
	    rb_warn("following states will not be copied in the future version:");
	    if (klass) {
		rb_warn("  subclass: %+"PRIsVALUE, klass);
	    }
	    if (FL_TEST(hash, FL_EXIVAR)) {
		rb_warn("  instance variables: %+"PRIsVALUE,
			rb_obj_instance_variables(hash));
	    }
	    if (FL_TEST(hash, FL_TAINT)) {
		rb_warn("  taintedness");
	    }
	    if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
		rb_warn("  default proc: %+"PRIsVALUE, RHASH_IFNONE(hash));
	    }
	    else if (!NIL_P(RHASH_IFNONE(hash)))
		rb_warn("  default value: %+"PRIsVALUE, RHASH_IFNONE(hash));
#else
	    rb_warn("extra states are no longer copied: %+"PRIsVALUE, hash);
#endif
	}
    }
#if HASH_REJECT_COPY_EXTRA_STATES
    result = rb_hash_dup_empty(hash);
#else
    result = rb_hash_new();
#endif
    if (!RHASH_EMPTY_P(hash)) {
	rb_hash_foreach(hash, reject_i, result);
    }
    return result;
}

#reject! {|key, value| ... } ⇒ Hash? #reject!Object

Equivalent to Hash#delete_if, but returns nil if no changes were made.

Overloads:

  • #reject! {|key, value| ... } ⇒ Hash?

    Yields:

    Returns:



1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
# File 'hash.c', line 1112

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(hash)->ntbl->num_entries) return Qnil;
    return hash;
}

#replace(other_hash) ⇒ Hash

Replaces the contents of hsh with the contents of other_hash.

h = { "a" => 100, "b" => 200 }
h.replace({ "c" => 300, "d" => 400 })   #=> {"c"=>300, "d"=>400}

Returns:



1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
# File 'hash.c', line 1467

static VALUE
rb_hash_replace(VALUE hash, VALUE hash2)
{
    st_table *table2;

    rb_hash_modify_check(hash);
    if (hash == hash2) return hash;
    hash2 = to_hash(hash2);

    RHASH_SET_IFNONE(hash, RHASH_IFNONE(hash2));
    if (FL_TEST(hash2, HASH_PROC_DEFAULT))
	FL_SET(hash, HASH_PROC_DEFAULT);
    else
	FL_UNSET(hash, HASH_PROC_DEFAULT);

    table2 = RHASH(hash2)->ntbl;

    rb_hash_clear(hash);
    if (table2) hash_tbl(hash)->type = table2->type;
    rb_hash_foreach(hash2, replace_i, hash);

    return hash;
}

#select {|key, value| ... } ⇒ Hash #selectObject

Returns a new hash consisting of entries for which the block returns true.

If no block is given, an enumerator is returned instead.

h = { "a" => 100, "b" => 200, "c" => 300 }
h.select {|k,v| k > "a"}  #=> {"b" => 200, "c" => 300}
h.select {|k,v| v < 200}  #=> {"a" => 100}

Overloads:

  • #select {|key, value| ... } ⇒ Hash

    Yields:

    Returns:



1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
# File 'hash.c', line 1238

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| ... } ⇒ Hash? #select!Object

Equivalent to Hash#keep_if, but returns nil if no changes were made.

Overloads:

  • #select! {|key, value| ... } ⇒ Hash?

    Yields:

    Returns:



1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
# File 'hash.c', line 1269

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);
    if (!RHASH(hash)->ntbl)
        return Qnil;
    n = RHASH(hash)->ntbl->num_entries;
    rb_hash_foreach(hash, keep_if_i, hash);
    if (n == RHASH(hash)->ntbl->num_entries) return Qnil;
    return hash;
}

#shiftArray, Object

Removes a key-value pair from hsh and returns it as the two-item array [ key, value ], or the hash’s default value if the hash is empty.

h = { 1 => "a", 2 => "b", 3 => "c" }
h.shift   #=> [1, "a"]
h         #=> {2=>"b", 3=>"c"}

Returns:



1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
# File 'hash.c', line 1037

static VALUE
rb_hash_shift(VALUE hash)
{
    struct shift_var var;

    rb_hash_modify_check(hash);
    if (RHASH(hash)->ntbl) {
	var.key = Qundef;
	if (RHASH_ITER_LEV(hash) == 0) {
	    if (st_shift(RHASH(hash)->ntbl, &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_key(hash, var.key);
		return rb_assoc_new(var.key, var.val);
	    }
	}
    }
    return hash_default_value(hash, Qnil);
}

#lengthFixnum #sizeFixnum

Returns the number of key-value pairs in the hash.

h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
h.length        #=> 4
h.delete("a")   #=> 200
h.length        #=> 3

Overloads:



1504
1505
1506
1507
1508
# File 'hash.c', line 1504

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

#[]=(key) ⇒ Object #store(key, value) ⇒ Object

Element Assignment

Associates the value given by value with the key given by key.

h = { "a" => 100, "b" => 200 }
h["a"] = 9
h["c"] = 4
h   #=> {"a"=>9, "b"=>200, "c"=>4}
h.store("d", 42) #=> {"a"=>9, "b"=>200, "c"=>4, "d"=>42}

key should not have its value changed while it is in use as a key (an unfrozen String passed as a key will be duplicated and frozen).

a = "a"
b = "b".freeze
h = { a => 100, b => 200 }
h.key(100).equal? a #=> false
h.key(200).equal? b #=> true


1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
# File 'hash.c', line 1392

VALUE
rb_hash_aset(VALUE hash, VALUE key, VALUE val)
{
    int iter_lev = RHASH_ITER_LEV(hash);
    st_table *tbl = RHASH(hash)->ntbl;

    rb_hash_modify(hash);
    if (!tbl) {
	if (iter_lev > 0) no_new_key();
	tbl = hash_tbl(hash);
    }
    if (tbl->type == &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;
}

#to_aArray

Converts hsh to a nested array of [ key, value ] arrays.

h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  }
h.to_a   #=> [["c", 300], ["a", 100], ["d", 400]]

Returns:



1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
# File 'hash.c', line 1659

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);
    OBJ_INFECT(ary, hash);

    return ary;
}

#to_hHash

Returns self. If called on a subclass of Hash, converts the receiver to a Hash object.

Returns:



1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
# File 'hash.c', line 1747

static VALUE
rb_hash_to_h(VALUE hash)
{
    if (rb_obj_class(hash) != rb_cHash) {
	VALUE ret = rb_hash_new();
	if (!RHASH_EMPTY_P(hash))
	    RHASH(ret)->ntbl = st_copy(RHASH(hash)->ntbl);
	if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
	    FL_SET(ret, HASH_PROC_DEFAULT);
	}
	RHASH_SET_IFNONE(ret, RHASH_IFNONE(hash));
	return ret;
    }
    return hash;
}

#to_hashHash

Returns self.

Returns:



1733
1734
1735
1736
1737
# File 'hash.c', line 1733

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

#merge!(other_hash) ⇒ Hash #update(other_hash) ⇒ Hash #merge!(other_hash) {|key, oldval, newval| ... } ⇒ Hash #update(other_hash) {|key, oldval, newval| ... } ⇒ Hash

Adds the contents of other_hash to hsh. If no block is specified, entries with duplicate keys are overwritten with the values from other_hash, otherwise the value of each duplicate key is determined by calling the block with the key, its value in hsh and its value in other_hash.

h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h1.merge!(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}

h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h1.merge!(h2) { |key, v1, v2| v1 }
                #=> {"a"=>100, "b"=>200, "c"=>300}

Overloads:

  • #merge!(other_hash) ⇒ Hash

    Returns:

  • #update(other_hash) ⇒ Hash

    Returns:

  • #merge!(other_hash) {|key, oldval, newval| ... } ⇒ Hash

    Yields:

    • (key, oldval, newval)

    Returns:

  • #update(other_hash) {|key, oldval, newval| ... } ⇒ Hash

    Yields:

    • (key, oldval, newval)

    Returns:



2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
# File 'hash.c', line 2155

static VALUE
rb_hash_update(VALUE hash1, VALUE hash2)
{
    rb_hash_modify(hash1);
    hash2 = to_hash(hash2);
    if (rb_block_given_p()) {
	rb_hash_foreach(hash2, rb_hash_update_block_i, hash1);
    }
    else {
	rb_hash_foreach(hash2, rb_hash_update_i, hash1);
    }
    return hash1;
}

#has_value?(value) ⇒ Boolean #value?(value) ⇒ Boolean

Returns true if the given value is present for some key in hsh.

h = { "a" => 100, "b" => 200 }
h.has_value?(100)   #=> true
h.has_value?(999)   #=> false

Overloads:

  • #has_value?(value) ⇒ Boolean

    Returns:

    • (Boolean)
  • #value?(value) ⇒ Boolean

    Returns:

    • (Boolean)

Returns:

  • (Boolean)


1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
# File 'hash.c', line 1902

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

#valuesArray

Returns a new array populated with the values from hsh. See also Hash#keys.

h = { "a" => 100, "b" => 200, "c" => 300 }
h.values   #=> [100, 200, 300]

Returns:



1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
# File 'hash.c', line 1826

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)) {
	st_table *table = RHASH(hash)->ntbl;

	if (OBJ_PROMOTED(values)) rb_gc_writebarrier_remember_promoted(values);
	RARRAY_PTR_USE(values, ptr, {
	    size = st_values_check(table, ptr, size, Qundef);
	});
	rb_ary_set_len(values, size);
    }
    else {
	rb_hash_foreach(hash, values_i, values);
    }

    return values;
}

#values_at(key, ...) ⇒ Array

Return an array containing the values associated with the given keys. Also see Hash.select.

h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
h.values_at("cow", "cat")  #=> ["bovine", "feline"]

Returns:



1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
# File 'hash.c', line 1203

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