0

请按照以下代码:

第一部分

> h = { "a" => 100, "b" => 200 }
=> {"a"=>100, "b"=>200}
> h.default = "Go fish"
=> "Go fish"
> h["a"]
=> 100
> h["z"]
=> "Go fish"
> h.default = proc do |hash, key|
*   hash[key] = key + key
> end
=> #<Proc:0x208bee8@(irb):5>
> h[2]
=> #<Proc:0x208bee8@(irb):5>
> h["cat"]
=> #<Proc:0x208bee8@(irb):5>

第二部分

> h = { "a" => 100, "b" => 200 }
=> {"a"=>100, "b"=>200}
> h.default_proc = proc do |hash, key|
*   hash[key] = key + key
> end
=> #<Proc:0x1e21df8@(irb):2>
> h[2]
=> 4
> h["cat"]
=> "catcat"

现在我很惊讶地看到,为什么h[2] and h["cat"]part-I and part-II.

你能解释一下吗?

4

2 回答 2

2

为什么?(哲学的)

如果你想要一个Procs 的哈希值怎么办?您不能只将默认设置为 a Proc to run,因为不会有(微不足道的)机制将它与 a Procto return区分开来。

s 的映射Proc可用于实现简单的状态机或外部 DSL。

为什么?(技术的)

因为是这样[]写的:

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

    if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
        if (!FL_TEST(hash, HASH_PROC_DEFAULT) &&
            rb_method_basic_definition_p(CLASS_OF(hash), id_default)) {
            return RHASH_IFNONE(hash);
        }
        else {
            return rb_funcall(hash, id_default, 1, key);
        }
    }
    return (VALUE)val;
}

正如文档default所说:

无法将默认值设置为将在每次键查找时执行的 Proc。

于 2013-01-13T14:20:32.850 回答
2
  • Hash#default=设置在没有这样的键的情况下要返回的值。您在 Part-I 中将其设置为 proc,这就是您看到的返回内容。
  • Hash#default_proc=设置要在自身和密钥上调用的 proc ,以防没有这样的密钥。如果你这样做了hash[2] = 2 + 2,那么hash[2]就会返回4。如果你这样做了hash["cat"] = "cat" + "cat",那么hash["cat"]就会返回"catcat"
于 2013-01-13T14:26:17.697 回答