[ruby-trunk - Feature #5553][Open] A method for Hash that works differently depending on whether a k

Issue #5553 has been reported by Tsuyoshi Sawada.


Feature #5553: A method for Hash that works differently depending on
whether a key exists

Author: Tsuyoshi Sawada
Status: Open
Priority: Normal
Assignee:
Category:
Target version:

A method Hash#if_key(key, [default], &pr) which works like the following
will be often used, and is useful.

a = {morning: "おはよう", daytime: "こんにちは", evening: "こんばんは", nothing: 

nil}
a.if_key(:morning){|str| “#{str}世界!”} #=> “おはよう世界!”
a.if_key(:nothing){|str| “#{str}世界!”} #=> “世界!”
a.if_key(:midnight){|str| “#{str}世界!”} #=> nil
a.if_key(:nothing, “どうも”){|str| “#{str}世界!”} #=> “どうも”

That is, when key' exists, then the corresponding value will be passed to pr’. Otherwise, the given `default’ or the implicit default will be
returned.

Issue #5553 has been updated by Alexey M…

In your example, the :nothing key exists, so shouldn’t it be
a.if_key(:nothing, “どうも”){|str| “#{str}世界!”} #=> “世界!” ?

Why would the code with this method be better than the following one:

if a.has_key?(key)

block here

else

default value or another block here

end

or ( a.has_key?(key) ? simple operation : default )

This seems easier to read.

If you plan to always use it with the same block, maybe it should be
made into a separate class with an appropriate method?

Feature #5553: A method for Hash that works differently depending on
whether a key exists

Author: Tsuyoshi Sawada
Status: Open
Priority: Normal
Assignee:
Category:
Target version:

A method Hash#if_key(key, [default], &pr) which works like the following
will be often used, and is useful.

a = {morning: "おはよう", daytime: "こんにちは", evening: "こんばんは", nothing: 

nil}
a.if_key(:morning){|str| “#{str}世界!”} #=> “おはよう世界!”
a.if_key(:nothing){|str| “#{str}世界!”} #=> “世界!”
a.if_key(:midnight){|str| “#{str}世界!”} #=> nil
a.if_key(:nothing, “どうも”){|str| “#{str}世界!”} #=> “どうも”

That is, when key' exists, then the corresponding value will be passed to pr’. Otherwise, the given `default’ or the implicit default will be
returned.

Issue #5553 has been updated by Tsuyoshi Sawada.

The whole point of this suggestion is that I feel some redundancy to
have to call the method fetch or [] on the hash after checking that
the key exists using key?. With this proposed method, the method call
fetch or [] is unnecessary, and you can just refer to a block
variable.

Feature #5553: A method for Hash that works differently depending on
whether a key exists

Author: Tsuyoshi Sawada
Status: Open
Priority: Normal
Assignee:
Category:
Target version:

A method Hash#if_key(key, [default], &pr) which works like the following
will be often used, and is useful.

a = {morning: "おはよう", daytime: "こんにちは", evening: "こんばんは", nothing: 

nil}
a.if_key(:morning){|str| “#{str}世界!”} #=> “おはよう世界!”
a.if_key(:nothing){|str| “#{str}世界!”} #=> “世界!”
a.if_key(:midnight){|str| “#{str}世界!”} #=> nil
a.if_key(:nothing, “どうも”){|str| “#{str}世界!”} #=> “どうも”

That is, when key' exists, then the corresponding value will be passed to pr’. Otherwise, the given `default’ or the implicit default will be
returned.

Issue #5553 has been updated by Alexey M…

I see. But then you may also want to pass a second procedure which is
run if the key does not exist, and to have both the key and the value
passed to the procedures, that is to introduce a method of the form
#fetch_and_use(key, proc_if_key_found, proc_if_not), but this will cost
having to store the procedures in variables for a one-time use. Also I
am afraid that optimizing like this for all possible use cases may
require introducing many new methods.

On the other hand, if you want to use a hash in this way with same
procedures multiple times, then what about adding a method
Hash#on_found_proc= analogous to Hash#default_proc= to be able to
do like this:

a = {morning: “おはよう”, daytime: “こんにちは”, evening: “こんばんは”, nothing: nil}
a.default = “どうも”
a.on_found_proc = proc do |hash,key,value|
“#{value}世界!”
end
a[:morning] # => “おはよう世界!”
a[:night] # => “どうも”


Feature #5553: A method for Hash that works differently depending on
whether a key exists

Author: Tsuyoshi Sawada
Status: Feedback
Priority: Normal
Assignee:
Category:
Target version:

A method Hash#if_key(key, [default], &pr) which works like the following
will be often used, and is useful.

a = {morning: "おはよう", daytime: "こんにちは", evening: "こんばんは", nothing: 

nil}
a.if_key(:morning){|str| “#{str}世界!”} #=> “おはよう世界!”
a.if_key(:nothing){|str| “#{str}世界!”} #=> “世界!”
a.if_key(:midnight){|str| “#{str}世界!”} #=> nil
a.if_key(:nothing, “どうも”){|str| “#{str}世界!”} #=> “どうも”

That is, when key' exists, then the corresponding value will be passed to pr’. Otherwise, the given `default’ or the implicit default will be
returned.

Issue #5553 has been updated by mame (Yusuke E.).

Status changed from Feedback to Rejected

No feedback, looks hopeless to me. Closing.


Yusuke E. [email protected]

Feature #5553: A method for Hash that works differently depending on
whether a key exists

Author: sawa (Tsuyoshi Sawada)
Status: Rejected
Priority: Normal
Assignee:
Category:
Target version:

A method Hash#if_key(key, [default], &pr) which works like the following
will be often used, and is useful.

a = {morning: "おはよう", daytime: "こんにちは", evening: "こんばんは", nothing: 

nil}
a.if_key(:morning){|str| “#{str}世界!”} #=> “おはよう世界!”
a.if_key(:nothing){|str| “#{str}世界!”} #=> “世界!”
a.if_key(:midnight){|str| “#{str}世界!”} #=> nil
a.if_key(:nothing, “どうも”){|str| “#{str}世界!”} #=> “どうも”

That is, when key' exists, then the corresponding value will be passed to pr’. Otherwise, the given `default’ or the implicit default will be
returned.

Issue #5553 has been updated by Yukihiro M…

Status changed from Open to Feedback

「fetchや[]を頻繁に呼びたくない」という意図は伝わらないでも無いですが、でもそれよりもif_keyメソッドのほうが嬉しい局面というのがあまり想像できません。単にメソッドでラップすればいいんじゃないですか?
正直、この例では全然嬉しくないと思います。もうちょっと人工的でない例だと嬉しさがイメージできるかもしれません。

Feature #5553: A method for Hash that works differently depending on
whether a key exists

Author: Tsuyoshi Sawada
Status: Feedback
Priority: Normal
Assignee:
Category:
Target version:

A method Hash#if_key(key, [default], &pr) which works like the following
will be often used, and is useful.

a = {morning: "おはよう", daytime: "こんにちは", evening: "こんばんは", nothing: 

nil}
a.if_key(:morning){|str| “#{str}世界!”} #=> “おはよう世界!”
a.if_key(:nothing){|str| “#{str}世界!”} #=> “世界!”
a.if_key(:midnight){|str| “#{str}世界!”} #=> nil
a.if_key(:nothing, “どうも”){|str| “#{str}世界!”} #=> “どうも”

That is, when key' exists, then the corresponding value will be passed to pr’. Otherwise, the given `default’ or the implicit default will be
returned.