Hash#default=
sets the value to be returned in case there is no such key. You set that to a proc in Part-I, and that is what you see being returned.Hash#default_proc=
sets the proc to be called on itself and the key in case there is no such key. If you dohash[2] = 2 + 2
, thenhash[2]
will return4
. If you dohash["cat"] = "cat" + "cat"
, thenhash["cat"]
will return"catcat"
.
default value are not properly reflected for the same keys from 2 different but closely related ruby code
-
15-01-2022 - |
Question
Please follow the below code :
Part-I
> 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>
Part-II
> 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"
Now I am surprised to see, why h[2] and h["cat"]
giving different output for the two codes in part-I and part-II
.
Could you anyone please explain?
Solution
OTHER TIPS
Why? (Philosophical)
What if you wanted a hash of Proc
s? You can't just set the default value to be a Proc
to run, because there wouldn't be a (trivial) mechanism to distinguish it from a Proc
to return.
Maps of Proc
s might be used to implement a simple state machine or external DSL.
Why? (Technical)
Because that's the way []
is written:
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;
}
As the docs to default
say:
It is not possible to set the default to a Proc that will be executed on each key lookup.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow