hash.c: implement typical part of merge in C.
MODIFY
mrbgems/mruby-hash-ext/mrblib/hash.rb
mrbgems/mruby-hash-ext/mrblib/hash.rb
@@ -83,6 +83,7 @@ class Hash
def merge!(*others, &block)
i = 0; len=others.size
+ return self.__merge(*others) unless block
while i<len
other = others[i]
i += 1

MODIFY
mrblib/hash.rb
mrblib/hash.rb
@@ -161,17 +161,14 @@ class Hash
def merge(*others, &block)
i=0; len=others.size
h = self.dup
+ return h.__merge(*others) unless block
while i<len
other = others[i]
i += 1
raise TypeError, "Hash required (#{other.class} given)" unless Hash === other
- if block
other.each_key{|k|
h[k] = (self.has_key?(k))? block.call(k, self[k], other[k]): other[k]
}
- else
- other.each_key{|k| h[k] = other[k]}
- end
end
h
end

MODIFY
src/hash.c
src/hash.c
@@ -1746,6 +1746,19 @@ mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2)
});
}
+static mrb_value
+mrb_hash_merge_m(mrb_state *mrb, mrb_value hash)
+{
+ mrb_int argc;
+ mrb_value *argv;
+
+ mrb_get_args(mrb, "*", &argv, &argc);
+ while (argc--) {
+ mrb_hash_merge(mrb, hash, *argv++);
+ }
+ return hash;
+}
+
/*
* call-seq:
* hsh.rehash -> hsh
@@ -1806,4 +1819,5 @@ mrb_init_hash(mrb_state *mrb)
mrb_define_method(mrb, h, "value?", mrb_hash_has_value, MRB_ARGS_REQ(1)); /* 15.2.13.4.27 */
mrb_define_method(mrb, h, "values", mrb_hash_values, MRB_ARGS_NONE()); /* 15.2.13.4.28 */
mrb_define_method(mrb, h, "rehash", mrb_hash_rehash, MRB_ARGS_NONE());
+ mrb_define_method(mrb, h, "__merge", mrb_hash_merge_m, MRB_ARGS_REQ(1));
}

hash.c: implement typical part of merge in C.