diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2014-09-19 00:36:33 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2014-09-19 00:36:33 +0900 |
| commit | 02b2ac8de2ea12b97bc80aab0d582cda4634e71c (patch) | |
| tree | 91564b430a63534d98166b3200efb04d34777838 /mrbgems/mruby-hash-ext | |
| parent | e4bd48f3f724216ee1a8e77ad1afb2e1dae79099 (diff) | |
| parent | 5f16c41753f7789065f2c2bfe84395cad8cadcaa (diff) | |
| download | mruby-02b2ac8de2ea12b97bc80aab0d582cda4634e71c.tar.gz mruby-02b2ac8de2ea12b97bc80aab0d582cda4634e71c.zip | |
Merge pull request #2594 from yasuyuki/hash
Implement Hash[]
Diffstat (limited to 'mrbgems/mruby-hash-ext')
| -rw-r--r-- | mrbgems/mruby-hash-ext/mrblib/hash.rb | 52 | ||||
| -rw-r--r-- | mrbgems/mruby-hash-ext/test/hash.rb | 38 |
2 files changed, 90 insertions, 0 deletions
diff --git a/mrbgems/mruby-hash-ext/mrblib/hash.rb b/mrbgems/mruby-hash-ext/mrblib/hash.rb index 9da08dc3a..f214cb1d5 100644 --- a/mrbgems/mruby-hash-ext/mrblib/hash.rb +++ b/mrbgems/mruby-hash-ext/mrblib/hash.rb @@ -5,6 +5,58 @@ class Hash ## # call-seq: + # Hash[ key, value, ... ] -> new_hash + # Hash[ [ [key, value], ... ] ] -> new_hash + # Hash[ object ] -> new_hash + # + # Creates a new hash populated with the given objects. + # + # Similar to the literal <code>{ _key_ => _value_, ... }</code>. In the first + # form, keys and values occur in pairs, so there must be an even number of + # arguments. + # + # The second and third form take a single argument which is either an array + # of key-value pairs or an object convertible to a hash. + # + # Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200} + # Hash[ [ ["a", 100], ["b", 200] ] ] #=> {"a"=>100, "b"=>200} + # Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200} + # + + def self.[](*object) + o = object[0] + if o.respond_to?(:to_hash) + h = Hash.new + object[0].to_hash.each { |k, v| h[k] = v } + return h + elsif o.respond_to?(:to_a) + h = Hash.new + o.to_a.each do |i| + raise ArgumentError, "wrong element type #{i.class} (expected array)" unless i.respond_to?(:to_a) + k, v = nil + case i.size + when 2 + k = i[0] + v = i[1] + when 1 + k = i[0] + else + raise ArgumentError, "invalid number of elements (#{i.size} for 1..2)" + end + h[k] = v + end + return h + end + raise ArgumentError, 'odd number of arguments for Hash' unless object.length % 2 == 0 + h = Hash.new + 0.step(object.length - 2, 2) do |i| + h[object[i]] = object[i + 1] + end + h + end + + ## + # call-seq: # hsh.merge!(other_hash) -> hsh # hsh.merge!(other_hash){|key, oldval, newval| block} -> hsh # diff --git a/mrbgems/mruby-hash-ext/test/hash.rb b/mrbgems/mruby-hash-ext/test/hash.rb index 2bc5b911a..e1afdaaa3 100644 --- a/mrbgems/mruby-hash-ext/test/hash.rb +++ b/mrbgems/mruby-hash-ext/test/hash.rb @@ -1,6 +1,44 @@ ## # Hash(Ext) Test +assert('Hash.[] Hash') do + a = Hash['a_key' => 'a_value'] + + assert_equal({'a_key' => 'a_value'}, a) +end + +assert('Hash.[] [ [ ["b_key", "b_value" ] ] ]') do + a = Hash[ [ ['b_key', 'b_value'] ] ] + + assert_equal({'b_key' => 'b_value'}, a) + + a = Hash[ [ ] ] + + assert_equal({}, a) + + assert_raise(ArgumentError) do + Hash[ [ ['b_key', 'b_value', 'b_over'] ] ] + end + + assert_raise(ArgumentError) do + Hash[ [ [] ] ] + end +end + +assert('Hash.[] "c_key", "c_value"') do + a = Hash['c_key', 'c_value', 'd_key', 1] + + assert_equal({'c_key' => 'c_value', 'd_key' => 1}, a) + + a = Hash[] + + assert_equal({}, a) + + assert_raise(ArgumentError) do + Hash['d_key'] + end +end + assert('Hash#merge!') do a = { 'abc_key' => 'abc_value', 'cba_key' => 'cba_value' } b = { 'cba_key' => 'XXX', 'xyz_key' => 'xyz_value' } |
