/*
 *  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 <code>IndexError</code> exception; if <i>default</i> 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")
 *     
 *  <em>produces:</em>
 *     
 *     prog.rb:2:in `fetch': key not found (IndexError)
 *      from prog.rb:2
 *     
 */

static VALUE
rb_hash_fetch(argc, argv, hash)
    int argc;
    VALUE *argv;
    VALUE hash;
{
    VALUE key, if_none;
    VALUE 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 (!st_lookup(RHASH(hash)->tbl, key, &val)) {
        if (block_given) return rb_yield(key);
        if (argc == 1) {
            rb_raise(rb_eIndexError, "key not found");
        }
        return if_none;
    }
    return val;
}