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

Posted by Tsuyoshi Sawada (Guest)
on 2011-11-02 19:43
(Received via mailing list)
Issue #5553 has been reported by Tsuyoshi Sawada.

----------------------------------------
Feature #5553: A method for Hash that works differently depending on 
whether a key exists
http://redmine.ruby-lang.org/issues/5553

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.
Posted by Alexey Muranov (alexey_m)
on 2011-11-02 23:23
(Received via mailing list)
Issue #5553 has been updated by Alexey Muranov.


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
http://redmine.ruby-lang.org/issues/5553

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.
Posted by Tsuyoshi Sawada (Guest)
on 2011-11-03 09:44
(Received via mailing list)
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
http://redmine.ruby-lang.org/issues/5553

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.
Posted by Yukihiro Matsumoto (Guest)
on 2011-11-03 11:50
(Received via mailing list)
Issue #5553 has been updated by Yukihiro Matsumoto.

Status changed from Open to Feedback

「fetchや[]を頻繁に呼びたくない」という意図は伝わらないでも無いですが、でもそれよりもif_keyメソッドのほうが嬉しい局面というのがあまり想像できません。単にメソッドでラップすればいいんじゃないですか?
正直、この例では全然嬉しくないと思います。もうちょっと人工的でない例だと嬉しさがイメージできるかもしれません。
----------------------------------------
Feature #5553: A method for Hash that works differently depending on 
whether a key exists
http://redmine.ruby-lang.org/issues/5553

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.
Posted by Alexey Muranov (alexey_m)
on 2011-11-03 12:44
(Received via mailing list)
Issue #5553 has been updated by Alexey Muranov.


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
http://redmine.ruby-lang.org/issues/5553

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.
Posted by mame (Yusuke Endoh) (Guest)
on 2012-11-20 13:00
(Received via mailing list)
Issue #5553 has been updated by mame (Yusuke Endoh).

Status changed from Feedback to Rejected

No feedback, looks hopeless to me.  Closing.

--
Yusuke Endoh <mame@tsg.ne.jp>
----------------------------------------
Feature #5553: A method for Hash that works differently depending on 
whether a key exists
https://bugs.ruby-lang.org/issues/5553#change-33201

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.
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.