Skip to content

Commit

Permalink
Merge branch 'master' of github.com:mruby/mruby
Browse files Browse the repository at this point in the history
  • Loading branch information
matz committed May 8, 2013
2 parents 595b199 + c80103e commit 8e45630
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 94 deletions.
62 changes: 62 additions & 0 deletions mrbgems/mruby-hash-ext/src/hash-ext.c
@@ -0,0 +1,62 @@
/*
** hash.c - Hash class
**
** See Copyright Notice in mruby.h
*/

#include "mruby.h"
#include "mruby/array.h"
#include "mruby/class.h"
#include "mruby/hash.h"
#include "mruby/khash.h"
#include "mruby/string.h"
#include "mruby/variable.h"

/*
* call-seq:
* hsh.values_at(key, ...) -> array
*
* Return an array containing the values associated with the given keys.
* Also see <code>Hash.select</code>.
*
* h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
* h.values_at("cow", "cat") #=> ["bovine", "feline"]
*/

mrb_value
mrb_hash_values_at(mrb_state *mrb, int argc, mrb_value *argv, mrb_value hash)
{
mrb_value result = mrb_ary_new_capa(mrb, argc);
long i;

for (i=0; i<argc; i++) {
mrb_ary_push(mrb, result, mrb_hash_get(mrb, hash, argv[i]));
}
return result;
}

static mrb_value
hash_values_at(mrb_state *mrb, mrb_value hash)
{
mrb_value *argv;
int argc;

mrb_get_args(mrb, "*", &argv, &argc);

return mrb_hash_values_at(mrb, argc, argv, hash);
}

void
mrb_mruby_hash_ext_gem_init(mrb_state *mrb)
{
struct RClass *h;

h = mrb->hash_class;

mrb_define_method(mrb, h, "values_at", hash_values_at, MRB_ARGS_ANY());
}

void
mrb_mruby_hash_ext_gem_final(mrb_state *mrb)
{
}
6 changes: 6 additions & 0 deletions mrbgems/mruby-hash-ext/test/hash.rb
Expand Up @@ -18,3 +18,9 @@
'xyz_key' => 'xyz_value' }
end

assert('Hash#values_at') do
h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
result = h.values_at("cow", "cat")

result == ["bovine", "feline"]
end
45 changes: 45 additions & 0 deletions mrblib/hash.rb
Expand Up @@ -24,6 +24,23 @@ def delete(key, &block)
# Calls the given block for each element of +self+
# and pass the key and value of each element.
#
# call-seq:
# hsh.each {| key, value | block } -> hsh
# hsh.each_pair {| key, value | block } -> hsh
# hsh.each -> an_enumerator
# hsh.each_pair -> an_enumerator
#
#
# If no block is given, an enumerator is returned instead.
#
# h = { "a" => 100, "b" => 200 }
# h.each {|key, value| puts "#{key} is #{value}" }
#
# <em>produces:</em>
#
# a is 100
# b is 200
#
# ISO 15.2.13.4.9
def each(&block)
self.keys.each{|k| block.call([k, self[k]])}
Expand All @@ -34,6 +51,20 @@ def each(&block)
# Calls the given block for each element of +self+
# and pass the key of each element.
#
# call-seq:
# hsh.each_key {| key | block } -> hsh
# hsh.each_key -> an_enumerator
#
# If no block is given, an enumerator is returned instead.
#
# h = { "a" => 100, "b" => 200 }
# h.each_key {|key| puts key }
#
# <em>produces:</em>
#
# a
# b
#
# ISO 15.2.13.4.10
def each_key(&block)
self.keys.each{|k| block.call(k)}
Expand All @@ -44,6 +75,20 @@ def each_key(&block)
# Calls the given block for each element of +self+
# and pass the value of each element.
#
# call-seq:
# hsh.each_value {| value | block } -> hsh
# hsh.each_value -> an_enumerator
#
# If no block is given, an enumerator is returned instead.
#
# h = { "a" => 100, "b" => 200 }
# h.each_value {|value| puts value }
#
# <em>produces:</em>
#
# 100
# 200
#
# ISO 15.2.13.4.11
def each_value(&block)
self.keys.each{|k| block.call(self[k])}
Expand Down
92 changes: 0 additions & 92 deletions src/hash.c
Expand Up @@ -324,12 +324,6 @@ mrb_hash_aget(mrb_state *mrb, mrb_value self)
return mrb_hash_get(mrb, self, key);
}

mrb_value
mrb_hash_lookup(mrb_state *mrb, mrb_value hash, mrb_value key)
{
return mrb_hash_get(mrb, hash, key);
}

/*
* call-seq:
* hsh.fetch(key [, default] ) -> obj
Expand Down Expand Up @@ -610,29 +604,6 @@ mrb_hash_shift(mrb_state *mrb, mrb_value hash)
*
*/

/*
* call-seq:
* hsh.values_at(key, ...) -> array
*
* Return an array containing the values associated with the given keys.
* Also see <code>Hash.select</code>.
*
* h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
* h.values_at("cow", "cat") #=> ["bovine", "feline"]
*/

mrb_value
mrb_hash_values_at(mrb_state *mrb, int argc, mrb_value *argv, mrb_value hash)
{
mrb_value result = mrb_ary_new_capa(mrb, argc);
long i;

for (i=0; i<argc; i++) {
mrb_ary_push(mrb, result, mrb_hash_get(mrb, hash, argv[i]));
}
return result;
}

/*
* call-seq:
* hsh.select {|key, value| block} -> a_hash
Expand Down Expand Up @@ -813,69 +784,6 @@ mrb_hash_empty_p(mrb_state *mrb, mrb_value self)
return mrb_bool_value(empty_p);
}

/* 15.2.13.4.11 */
/*
* call-seq:
* hsh.each_value {| value | block } -> hsh
* hsh.each_value -> an_enumerator
*
* Calls <i>block</i> once for each key in <i>hsh</i>, passing the
* value as a parameter.
*
* If no block is given, an enumerator is returned instead.
*
* h = { "a" => 100, "b" => 200 }
* h.each_value {|value| puts value }
*
* <em>produces:</em>
*
* 100
* 200
*/

/* 15.2.13.4.10 */
/*
* call-seq:
* hsh.each_key {| key | block } -> hsh
* hsh.each_key -> an_enumerator
*
* Calls <i>block</i> once for each key in <i>hsh</i>, passing the key
* as a parameter.
*
* If no block is given, an enumerator is returned instead.
*
* h = { "a" => 100, "b" => 200 }
* h.each_key {|key| puts key }
*
* <em>produces:</em>
*
* a
* b
*/

/* 15.2.13.4.9 */
/*
* call-seq:
* hsh.each {| key, value | block } -> hsh
* hsh.each_pair {| key, value | block } -> hsh
* hsh.each -> an_enumerator
* hsh.each_pair -> an_enumerator
*
* Calls <i>block</i> once for each key in <i>hsh</i>, passing the key-value
* pair as parameters.
*
* If no block is given, an enumerator is returned instead.
*
* h = { "a" => 100, "b" => 200 }
* h.each {|key, value| puts "#{key} is #{value}" }
*
* <em>produces:</em>
*
* a is 100
* b is 200
*
*/

static mrb_value
inspect_hash(mrb_state *mrb, mrb_value hash, int recur)
{
Expand Down
15 changes: 13 additions & 2 deletions test/t/hash.rb
Expand Up @@ -52,9 +52,12 @@

assert('Hash#default_proc', '15.2.13.4.7') do
a = Hash.new
b = Hash.new {|s,k| s[k] = k}
b = Hash.new {|s,k| s[k] = k + k}
c = b[2]
d = b['cat']

a.default_proc == nil and b.default_proc.class == Proc
a.default_proc == nil and b.default_proc.class == Proc and
c = 4 and d = 'catcat'
end

assert('Hash#delete', '15.2.13.4.8') do
Expand Down Expand Up @@ -278,3 +281,11 @@
h == {:two => 2, :four => 4}
end

# Not ISO specified

assert('Hash#inspect') do
h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 }
ret = h.to_s

ret = "{\"c\"=>300, \"a\"=>100, \"d\"=>400}"
end

0 comments on commit 8e45630

Please sign in to comment.