From a3ecd5c83d57fb1556a40113f1b0c69c87261e33 Mon Sep 17 00:00:00 2001 From: dave Date: Tue, 23 Dec 2003 16:21:17 +0000 Subject: RDoc comments for Fixnum, Float, and Hash. Add heuristic to RDoc to handle yaml/stringio git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5265 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- hash.c | 583 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 583 insertions(+) (limited to 'hash.c') diff --git a/hash.c b/hash.c index 36fbed0e54..b15bd2488b 100644 --- a/hash.c +++ b/hash.c @@ -195,6 +195,41 @@ rb_hash_new() return hash_alloc(rb_cHash); } +/* + * call-seq: + * Hash.new => hash + * Hash.new(obj) => aHash + * Hash.new {|hash, key| block } => aHash + * + * 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"] + * + */ + static VALUE rb_hash_initialize(argc, argv, hash) int argc; @@ -219,6 +254,19 @@ rb_hash_initialize(argc, argv, hash) return hash; } +/* + * call-seq: + * Hash[ [key =>|, value]* ] => hash + * + * Creates a new hash populated with the given objects. Equivalent to + * the literal { key, value, ... }. Keys and + * values occur in pairs, so there must be an even number of arguments. + * + * Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200} + * Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200} + * { "a" => 100, "b" => 200 } #=> {"a"=>100, "b"=>200} + */ + static VALUE rb_hash_s_create(argc, argv, klass) int argc; @@ -265,6 +313,26 @@ rb_hash_rehash_i(key, value, tbl) return ST_CONTINUE; } +/* + * call-seq: + * hsh.rehash -> hsh + * + * 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 + * IndexError 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 + */ + static VALUE rb_hash_rehash(hash) VALUE hash; @@ -280,6 +348,20 @@ rb_hash_rehash(hash) return hash; } +/* + * call-seq: + * hsh[key] => value + * + * Element Reference---Retrieves the value object corresponding + * to the key object. If not found, returns the a default value (see + * Hash::new for details). + * + * h = { "a" => 100, "b" => 200 } + * h["a"] #=> 100 + * h["c"] #=> nil + * + */ + VALUE rb_hash_aref(hash, key) VALUE hash, key; @@ -292,6 +374,35 @@ rb_hash_aref(hash, key) return val; } +/* + * call-seq: + * hsh.fetch(key [, default] ) => obj + * hsh.fetch(key) {| key | block } => obj + * + * 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 IndexError 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 (IndexError) + * from prog.rb:2 + * + */ + static VALUE rb_hash_fetch(argc, argv, hash) int argc; @@ -318,6 +429,27 @@ rb_hash_fetch(argc, argv, hash) return val; } +/* + * call-seq: + * hsh.default(key=nil) => obj + * + * 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 #=> 0 + * h.default(2) #=> 20 + */ + static VALUE rb_hash_default(argc, argv, hash) int argc; @@ -333,6 +465,26 @@ rb_hash_default(argc, argv, hash) return RHASH(hash)->ifnone; } +/* + * call-seq: + * hsh.default = obj => hsh + * + * Sets the default value, the value returned for a key that does not + * exist in the hash. It is not possible to set the a 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] #=> # + * h["cat"] #=> # + */ + static VALUE rb_hash_set_default(hash, ifnone) VALUE hash, ifnone; @@ -343,6 +495,21 @@ rb_hash_set_default(hash, ifnone) return ifnone; } +/* + * call-seq: + * hsh.default_proc -> anObject + * + * 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 #=> # + * a = [] #=> [] + * p.call(a, 2) + * a #=> [nil, nil, 4] + */ + + static VALUE rb_hash_default_proc(hash) VALUE hash; @@ -365,6 +532,18 @@ index_i(key, value, args) return ST_CONTINUE; } +/* + * call-seq: + * hsh.index(value) => key + * + * Returns the key for a given value. If not found, returns nil. + * + * h = { "a" => 100, "b" => 200 } + * h.index(200) #=> "b" + * h.index(999) #=> nil + * + */ + static VALUE rb_hash_index(hash, value) VALUE hash, value; @@ -379,6 +558,15 @@ rb_hash_index(hash, value) return args[1]; } +/* + * call-seq: + * hsh.indexes(key, ...) => array + * hsh.indices(key, ...) => array + * + * Deprecated in favor of Hash#select. + * + */ + static VALUE rb_hash_indexes(argc, argv, hash) int argc; @@ -398,6 +586,24 @@ rb_hash_indexes(argc, argv, hash) return indexes; } +/* + * call-seq: + * hsh.delete(key) => value + * hsh.delete(key) {| key | block } => value + * + * Deletes and returns a key-value pair 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" + * + */ + VALUE rb_hash_delete(hash, key) VALUE hash, key; @@ -438,6 +644,19 @@ shift_i(key, value, var) return ST_DELETE; } +/* + * call-seq: + * hsh.shift -> anArray or obj + * + * 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"} + */ + static VALUE rb_hash_shift(hash) VALUE hash; @@ -469,6 +688,18 @@ delete_if_i(key, value) return ST_CONTINUE; } +/* + * call-seq: + * hsh.delete_if {| key, value | block } -> hsh + * + * Deletes every key-value pair from hsh for which block + * evaluates to true. + * + * h = { "a" => 100, "b" => 200, "c" => 300 } + * h.delete_if {|key, value| key >= "b" } #=> {"a"=>100} + * + */ + VALUE rb_hash_delete_if(hash) VALUE hash; @@ -478,6 +709,14 @@ rb_hash_delete_if(hash) return hash; } +/* + * call-seq: + * hsh.reject! {| key, value | block } -> hsh or nil + * + * Equivalent to Hash#delete_if, but returns + * nil if no changes were made. + */ + VALUE rb_hash_reject_bang(hash) VALUE hash; @@ -488,6 +727,16 @@ rb_hash_reject_bang(hash) return hash; } +/* + * call-seq: + * hsh.reject {| key, value | block } -> a_hash + * + * Same as Hash#delete_if, but works on (and returns) a + * copy of the hsh. Equivalent to + * hsh.dup.delete_if. + * + */ + static VALUE rb_hash_reject(hash) VALUE hash; @@ -505,6 +754,17 @@ select_i(key, value, result) return ST_CONTINUE; } +/* + * call-seq: + * hsh.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"] +*/ + VALUE rb_hash_values_at(argc, argv, hash) int argc; @@ -520,6 +780,19 @@ rb_hash_values_at(argc, argv, hash) return result; } +/* + * call-seq: + * hsh.select {|key, value| block} => array + * + * Returns a new array consisting of [key,value] + * pairs for which the block returns true. + * Also see Hash.values_at. + * + * 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]] + */ + VALUE rb_hash_select(argc, argv, hash) int argc; @@ -543,6 +816,17 @@ clear_i(key, value, dummy) return ST_DELETE; } +/* + * call-seq: + * hsh.clear -> hsh + * + * Removes all key-value pairs from hsh. + * + * h = { "a" => 100, "b" => 200 } #=> {"a"=>100, "b"=>200} + * h.clear #=> {} + * + */ + static VALUE rb_hash_clear(hash) VALUE hash; @@ -553,6 +837,24 @@ rb_hash_clear(hash) return hash; } +/* + * call-seq: + * hsh[key] = value => value + * hsh.store(key, value) => value + * + * Element Assignment---Associates the value given by + * value with the key given by key. + * key should not have its value changed while it is in + * use as a key (a String passed as a key will be + * duplicated and frozen). + * + * h = { "a" => 100, "b" => 200 } + * h["a"] = 9 + * h["c"] = 4 + * h #=> {"a"=>9, "b"=>200, "c"=>4} + * + */ + VALUE rb_hash_aset(hash, key, val) VALUE hash, key, val; @@ -578,6 +880,18 @@ replace_i(key, val, hash) return ST_CONTINUE; } +/* + * call-seq: + * hsh.replace(other_hash) -> hsh + * + * 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} + * + */ + static VALUE rb_hash_replace(hash, hash2) VALUE hash, hash2; @@ -597,6 +911,19 @@ rb_hash_replace(hash, hash2) return hash; } +/* + * call-seq: + * hsh.length => fixnum + * hsh.size => fixnum + * + * 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 + */ + static VALUE rb_hash_size(hash) VALUE hash; @@ -604,6 +931,17 @@ rb_hash_size(hash) return INT2FIX(RHASH(hash)->tbl->num_entries); } + +/* + * call-seq: + * hsh.empty? => true or false + * + * Returns true if hsh contains no key-value pairs. + * + * {}.empty? #=> true + * + */ + static VALUE rb_hash_empty_p(hash) VALUE hash; @@ -622,6 +960,22 @@ each_value_i(key, value) return ST_CONTINUE; } +/* + * call-seq: + * hsh.each_value {| value | block } -> hsh + * + * Calls block once for each key in hsh, passing the + * value as a parameter. + * + * h = { "a" => 100, "b" => 200 } + * h.each_value {|value| puts value } + * + * produces: + * + * 100 + * 200 + */ + static VALUE rb_hash_each_value(hash) VALUE hash; @@ -639,6 +993,21 @@ each_key_i(key, value) return ST_CONTINUE; } +/* + * call-seq: + * hsh.each_key {| key | block } -> hsh + * + * Calls block once for each key in hsh, passing the key + * as a parameter. + * + * h = { "a" => 100, "b" => 200 } + * h.each_key {|key| puts key } + * + * produces: + * + * a + * b + */ static VALUE rb_hash_each_key(hash) VALUE hash; @@ -656,6 +1025,23 @@ each_pair_i(key, value) return ST_CONTINUE; } +/* + * call-seq: + * hsh.each_pair {| key_value_array | block } -> hsh + * + * Calls block once for each key in hsh, passing the key + * and value as parameters. + * + * h = { "a" => 100, "b" => 200 } + * h.each_pair {|key, value| puts "#{key} is #{value}" } + * + * produces: + * + * a is 100 + * b is 200 + * + */ + static VALUE rb_hash_each_pair(hash) VALUE hash; @@ -673,6 +1059,26 @@ each_i(key, value) return ST_CONTINUE; } +/* + * call-seq: + * hsh.each {| key, value | block } -> hsh + * + * Calls block once for each key in hsh, passing the key + * and value to the block as a two-element array. Because of the assignment + * semantics of block parameters, these elements will be split out if the + * block has two formal parameters. Also see Hash.each_pair, which + * will be marginally more efficient for blocks with two parameters. + * + * h = { "a" => 100, "b" => 200 } + * h.each {|key, value| puts "#{key} is #{value}" } + * + * produces: + * + * a is 100 + * b is 200 + * + */ + static VALUE rb_hash_each(hash) VALUE hash; @@ -690,6 +1096,17 @@ to_a_i(key, value, ary) return ST_CONTINUE; } +/* + * call-seq: + * hsh.to_a -> array + * + * Converts hsh to a nested array of [ key, + * value ] arrays. + * + * h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 } + * h.to_a #=> [["a", 100], ["c", 300], ["d", 400]] + */ + static VALUE rb_hash_to_a(hash) VALUE hash; @@ -703,6 +1120,21 @@ rb_hash_to_a(hash) return ary; } +/* + * call-seq: + * hsh.sort => array + * hsh.sort {| a, b | block } => array + * + * Converts hsh to a nested array of [ key, + * value ] arrays and sorts it, using + * Array#sort. + * + * h = { "a" => 20, "b" => 30, "c" => 10 } + * h.sort #=> [["a", 20], ["b", 30], ["c", 10]] + * h.sort {|a,b| a[1]<=>b[1]} #=> [["c", 10], ["a", 20], ["b", 30]] + * + */ + static VALUE rb_hash_sort(hash) VALUE hash; @@ -747,6 +1179,13 @@ inspect_hash(hash) return str; } +/* + * call-seq: + * hsh.inspect => string + * + * Return the contents of this hash as a string. + */ + static VALUE rb_hash_inspect(hash) VALUE hash; @@ -764,6 +1203,19 @@ to_s_hash(hash) return rb_ary_to_s(rb_hash_to_a(hash)); } +/* + * call-seq: + * hsh.to_s => string + * + * Converts hsh to a string by converting the hash to an array + * of [ key, value ] pairs and then + * converting that array to a string using Array#join with + * the default separator. + * + * h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 } + * h.to_s #=> "a100c300d400" + */ + static VALUE rb_hash_to_s(hash) VALUE hash; @@ -772,6 +1224,13 @@ rb_hash_to_s(hash) return rb_protect_inspect(to_s_hash, hash, 0); } +/* + * call-seq: + * hsh.to_hash => hsh + * + * Returns self. + */ + static VALUE rb_hash_to_hash(hash) VALUE hash; @@ -788,6 +1247,18 @@ keys_i(key, value, ary) return ST_CONTINUE; } +/* + * call-seq: + * hsh.keys => array + * + * 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"] + * + */ + static VALUE rb_hash_keys(hash) VALUE hash; @@ -809,6 +1280,18 @@ values_i(key, value, ary) return ST_CONTINUE; } +/* + * call-seq: + * hsh.values => array + * + * 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] + * + */ + static VALUE rb_hash_values(hash) VALUE hash; @@ -821,6 +1304,21 @@ rb_hash_values(hash) return ary; } +/* + * call-seq: + * hsh.has_key?(key) => true or false + * hsh.include?(key) => true or false + * hsh.key?(key) => true or false + * hsh.member?(key) => true or false + * + * 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 + * + */ + static VALUE rb_hash_has_key(hash, key) VALUE hash; @@ -844,6 +1342,19 @@ rb_hash_search_value(key, value, data) return ST_CONTINUE; } +/* + * call-seq: + * hsh.has_value?(value) => true or false + * hsh.value?(value) => true or false + * + * 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 + */ + static VALUE rb_hash_has_value(hash, val) VALUE hash; @@ -881,6 +1392,25 @@ equal_i(key, val1, data) return ST_CONTINUE; } +/* + * call-seq: + * hsh == other_hash => true or false + * + * 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 + * + */ + static VALUE rb_hash_equal(hash1, hash2) VALUE hash1, hash2; @@ -917,6 +1447,18 @@ rb_hash_invert_i(key, value, hash) return ST_CONTINUE; } +/* + * call-seq: + * hsh.invert -> aHash + * + * 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=>"n", 200=>"d", 300=>"y"} + * + */ + static VALUE rb_hash_invert(hash) VALUE hash; @@ -950,6 +1492,19 @@ rb_hash_update_block_i(key, value, hash) return ST_CONTINUE; } +/* + * call-seq: + * hsh.merge!(other_hash) => hsh + * hsh.update(other_hash) => hsh + * + * Adds the contents of other_hash to hsh, overwriting + * entries with duplicate keys with those from other_hash. + * + * h1 = { "a" => 100, "b" => 200 } + * h2 = { "b" => 254, "c" => 300 } + * h1.merge!(h2) #=> {"a"=>100, "b"=>254, "c"=>300} + */ + static VALUE rb_hash_update(hash1, hash2) VALUE hash1, hash2; @@ -964,6 +1519,21 @@ rb_hash_update(hash1, hash2) return hash1; } +/* + * call-seq: + * hsh.merge(other_hash) -> a_hash + * + * Returns a new hash containing the contents of other_hash and + * the contents of hsh, overwriting entries in hsh with + * duplicate keys with those from 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} + * + */ + static VALUE rb_hash_merge(hash1, hash2) VALUE hash1, hash2; @@ -1762,6 +2332,19 @@ env_update(env, hash) return env; } +/* + * A Hash is a collection of key-value pairs. It is + * similar to an Array, except that indexing is done via + * arbitrary keys of any object type, not an integer index. The order + * in which you traverse a hash by either key or value may seem + * arbitrary, and will generally not be in the insertion order. + * + * Hashes have a default value that is returned when accessing + * keys that do not exist in the hash. By default, that value is + * nil. + * + */ + void Init_Hash() { -- cgit v1.2.3