ruby-changes:18057
From: nobu <ko1@a...>
Date: Sat, 4 Dec 2010 11:25:16 +0900 (JST)
Subject: [ruby-changes:18057] Ruby:r30078 (trunk): * hash.c (rb_hash_update_by): new API for Hash#update.
nobu 2010-12-04 11:21:53 +0900 (Sat, 04 Dec 2010) New Revision: 30078 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=30078 Log: * hash.c (rb_hash_update_by): new API for Hash#update. Modified files: trunk/ChangeLog trunk/hash.c trunk/include/ruby/intern.h Index: include/ruby/intern.h =================================================================== --- include/ruby/intern.h (revision 30077) +++ include/ruby/intern.h (revision 30078) @@ -436,6 +436,8 @@ VALUE rb_hash_aset(VALUE, VALUE, VALUE); VALUE rb_hash_delete_if(VALUE); VALUE rb_hash_delete(VALUE,VALUE); +typedef VALUE rb_hash_update_func(VALUE newkey, VALUE oldkey, VALUE value); +VALUE rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func); struct st_table *rb_hash_tbl(VALUE); int rb_path_check(const char*); int rb_env_path_tainted(void); Index: ChangeLog =================================================================== --- ChangeLog (revision 30077) +++ ChangeLog (revision 30078) @@ -1,3 +1,7 @@ +Sat Dec 4 11:21:50 2010 Nobuyoshi Nakada <nobu@r...> + + * hash.c (rb_hash_update_by): new API for Hash#update. + Sat Dec 4 11:18:10 2010 Tanaka Akira <akr@f...> * class.c: parenthesize macro arguments. Index: hash.c =================================================================== --- hash.c (revision 30077) +++ hash.c (revision 30078) @@ -1785,6 +1785,43 @@ return hash1; } +struct update_arg { + VALUE hash; + rb_hash_update_func *func; +}; + +static int +rb_hash_update_func_i(VALUE key, VALUE value, VALUE arg0) +{ + struct update_arg *arg = (struct update_arg *)arg0; + VALUE hash = arg->hash; + + if (key == Qundef) return ST_CONTINUE; + if (rb_hash_has_key(hash, key)) { + value = (*arg->func)(key, rb_hash_aref(hash, key), value); + } + hash_update(hash, key); + st_insert(RHASH(hash)->ntbl, key, value); + return ST_CONTINUE; +} + +VALUE +rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func) +{ + rb_hash_modify(hash1); + hash2 = to_hash(hash2); + if (func) { + struct update_arg arg; + arg.hash = hash1; + arg.func = func; + rb_hash_foreach(hash2, rb_hash_update_func_i, (VALUE)&arg); + } + else { + rb_hash_foreach(hash2, rb_hash_update_i, hash1); + } + return hash1; +} + /* * call-seq: * hsh.merge(other_hash) -> new_hash -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/