Commit 4ffea85b authored by cremno's avatar cremno

hash / hash-ext: various small changes

src/hash.c:
 - mrb_hash_(aget|aset|dup|delete): internal linkage
 - remove documentation of methods which are not implemented (in here)
 - remove #assoc; unused, not in ISO spec
 - remove #rassoc: same, implementation is also wrong

hash-ext mrbgem:
 - remove header "mruby/khash.h"
 - remove mrb_hash_values_at (move code into hash_values_at, i: long -> int)
 - less whitespace in gem_init function
parent 7a32c7b1
......@@ -7,7 +7,6 @@
#include "mruby.h"
#include "mruby/array.h"
#include "mruby/hash.h"
#include "mruby/khash.h"
/*
* call-seq:
......@@ -20,27 +19,18 @@
* 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_value *argv, result;
int argc, i;
mrb_get_args(mrb, "*", &argv, &argc);
return mrb_hash_values_at(mrb, argc, argv, hash);
result = mrb_ary_new_capa(mrb, argc);
for (i = 0; i < argc; i++) {
mrb_ary_push(mrb, result, mrb_hash_get(mrb, hash, argv[i]));
}
return result;
}
void
......@@ -49,8 +39,7 @@ 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());
mrb_define_method(mrb, h, "values_at", hash_values_at, MRB_ARGS_ANY());
}
void
......
......@@ -133,7 +133,7 @@ mrb_hash_fetch(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value def)
}
void
mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val) /* mrb_hash_aset */
mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val)
{
khash_t(ht) *h;
khiter_t k;
......@@ -155,7 +155,7 @@ mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val) /* mr
return;
}
mrb_value
static mrb_value
mrb_hash_dup(mrb_state *mrb, mrb_value hash)
{
struct RHash* ret;
......@@ -270,41 +270,12 @@ mrb_hash_init_core(mrb_state *mrb, mrb_value hash)
return 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. Equivalent to
* the literal <code>{ <i>key</i> => <i>value</i>, ... }</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}
*/
static mrb_value
to_hash(mrb_state *mrb, mrb_value hash)
{
return mrb_convert_type(mrb, hash, MRB_TT_HASH, "Hash", "to_hash");
}
/*
* call-seq:
* Hash.try_convert(obj) -> hash or nil
*
* Try to convert <i>obj</i> into a hash, using to_hash method.
* Returns converted hash or nil if <i>obj</i> cannot be converted
* for any reason.
*
* Hash.try_convert({1=>2}) # => {1=>2}
* Hash.try_convert("1=>2") # => nil
*/
/* 15.2.13.4.2 */
/*
* call-seq:
......@@ -319,7 +290,7 @@ to_hash(mrb_state *mrb, mrb_value hash)
* h["c"] #=> nil
*
*/
mrb_value
static mrb_value
mrb_hash_aget(mrb_state *mrb, mrb_value self)
{
mrb_value key;
......@@ -328,35 +299,6 @@ mrb_hash_aget(mrb_state *mrb, mrb_value self)
return mrb_hash_get(mrb, self, key);
}
/*
* call-seq:
* hsh.fetch(key [, default] ) -> obj
* hsh.fetch(key) {| key | block } -> obj
*
* Returns a value from the hash for the given key. If the key can't be
* found, there are several options: With no other arguments, it will
* raise an <code>KeyError</code> exception; if <i>default</i> is
* given, then that will be returned; if the optional code block is
* specified, then that will be run and its result returned.
*
* h = { "a" => 100, "b" => 200 }
* h.fetch("a") #=> 100
* h.fetch("z", "go fish") #=> "go fish"
* h.fetch("z") { |el| "go fish, #{el}"} #=> "go fish, z"
*
* The following example shows that an exception is raised if the key
* is not found and a default value is not supplied.
*
* h = { "a" => 100, "b" => 200 }
* h.fetch("z")
*
* <em>produces:</em>
*
* prog.rb:2:in `fetch': key not found (KeyError)
* from prog.rb:2
*
*/
/* 15.2.13.4.5 */
/*
* call-seq:
......@@ -520,7 +462,7 @@ mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key)
* h.delete("z") { |el| "#{el} not found" } #=> "z not found"
*
*/
mrb_value
static mrb_value
mrb_hash_delete(mrb_state *mrb, mrb_value self)
{
mrb_value key;
......@@ -574,75 +516,6 @@ mrb_hash_shift(mrb_state *mrb, mrb_value hash)
}
}
/*
* call-seq:
* hsh.delete_if {| key, value | block } -> hsh
* hsh.delete_if -> an_enumerator
*
* Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
* evaluates to <code>true</code>.
*
* If no block is given, an enumerator is returned instead.
*
* h = { "a" => 100, "b" => 200, "c" => 300 }
* h.delete_if {|key, value| key >= "b" } #=> {"a"=>100}
*
*/
/*
* call-seq:
* hsh.reject! {| key, value | block } -> hsh or nil
* hsh.reject! -> an_enumerator
*
* Equivalent to <code>Hash#delete_if</code>, but returns
* <code>nil</code> if no changes were made.
*/
/*
* call-seq:
* hsh.reject {| key, value | block } -> a_hash
*
* Same as <code>Hash#delete_if</code>, but works on (and returns) a
* copy of the <i>hsh</i>. Equivalent to
* <code><i>hsh</i>.dup.delete_if</code>.
*
*/
/*
* call-seq:
* hsh.select {|key, value| block} -> a_hash
* hsh.select -> an_enumerator
*
* Returns a new hash consisting of entries for which the block returns true.
*
* If no block is given, an enumerator is returned instead.
*
* h = { "a" => 100, "b" => 200, "c" => 300 }
* h.select {|k,v| k > "a"} #=> {"b" => 200, "c" => 300}
* h.select {|k,v| v < 200} #=> {"a" => 100}
*/
/*
* call-seq:
* hsh.select! {| key, value | block } -> hsh or nil
* hsh.select! -> an_enumerator
*
* Equivalent to <code>Hash#keep_if</code>, but returns
* <code>nil</code> if no changes were made.
*/
/*
* call-seq:
* hsh.keep_if {| key, value | block } -> hsh
* hsh.keep_if -> an_enumerator
*
* Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
* evaluates to false.
*
* If no block is given, an enumerator is returned instead.
*
*/
/* 15.2.13.4.4 */
/*
* call-seq:
......@@ -683,7 +556,7 @@ mrb_hash_clear(mrb_state *mrb, mrb_value hash)
* h #=> {"a"=>9, "b"=>200, "c"=>4}
*
*/
mrb_value
static mrb_value
mrb_hash_aset(mrb_state *mrb, mrb_value self)
{
mrb_value key, val;
......@@ -1085,140 +958,6 @@ mrb_hash_eql(mrb_state *mrb, mrb_value hash1)
return hash_equal(mrb, hash1, hash2, TRUE);
}
/*
* call-seq:
* hsh.merge!(other_hash) -> hsh
* hsh.update(other_hash) -> hsh
* hsh.merge!(other_hash){|key, oldval, newval| block} -> hsh
* hsh.update(other_hash){|key, oldval, newval| block} -> hsh
*
* Adds the contents of <i>other_hash</i> to <i>hsh</i>. If no
* block is specified, entries with duplicate keys are overwritten
* with the values from <i>other_hash</i>, otherwise the value
* of each duplicate key is determined by calling the block with
* the key, its value in <i>hsh</i> and its value in <i>other_hash</i>.
*
* h1 = { "a" => 100, "b" => 200 }
* h2 = { "b" => 254, "c" => 300 }
* h1.merge!(h2) #=> {"a"=>100, "b"=>254, "c"=>300}
*
* h1 = { "a" => 100, "b" => 200 }
* h2 = { "b" => 254, "c" => 300 }
* h1.merge!(h2) { |key, v1, v2| v1 }
* #=> {"a"=>100, "b"=>200, "c"=>300}
*/
/* 15.2.13.4.22 */
/*
* call-seq:
* hsh.merge(other_hash) -> new_hash
* hsh.merge(other_hash){|key, oldval, newval| block} -> new_hash
*
* Returns a new hash containing the contents of <i>other_hash</i> and
* the contents of <i>hsh</i>. If no block is specified, the value for
* entries with duplicate keys will be that of <i>other_hash</i>. Otherwise
* the value for each duplicate key is determined by calling the block
* with the key, its value in <i>hsh</i> and its value in <i>other_hash</i>.
*
* h1 = { "a" => 100, "b" => 200 }
* h2 = { "b" => 254, "c" => 300 }
* h1.merge(h2) #=> {"a"=>100, "b"=>254, "c"=>300}
* h1.merge(h2){|key, oldval, newval| newval - oldval}
* #=> {"a"=>100, "b"=>54, "c"=>300}
* h1 #=> {"a"=>100, "b"=>200}
*
*/
/*
* call-seq:
* hash.assoc(obj) -> an_array or nil
*
* Searches through the hash comparing _obj_ with the key using <code>==</code>.
* Returns the key-value pair (two elements array) or +nil+
* if no match is found. See <code>Array#assoc</code>.
*
* h = {"colors" => ["red", "blue", "green"],
* "letters" => ["a", "b", "c" ]}
* h.assoc("letters") #=> ["letters", ["a", "b", "c"]]
* h.assoc("foo") #=> nil
*/
mrb_value
mrb_hash_assoc(mrb_state *mrb, mrb_value hash)
{
mrb_value key, value, has_key;
mrb_get_args(mrb, "o", &key);
if (mrb_nil_p(key))
mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
has_key = mrb_hash_has_keyWithKey(mrb, hash, key);
if (mrb_test(has_key)) {
value = mrb_hash_get(mrb, hash, key);
return mrb_assoc_new(mrb, key, value);
}
else {
return mrb_nil_value();
}
}
/*
* call-seq:
* hash.rassoc(key) -> an_array or nil
*
* Searches through the hash comparing _obj_ with the value using <code>==</code>.
* Returns the first key-value pair (two-element array) that matches. See
* also <code>Array#rassoc</code>.
*
* a = {1=> "one", 2 => "two", 3 => "three", "ii" => "two"}
* a.rassoc("two") #=> [2, "two"]
* a.rassoc("four") #=> nil
*/
mrb_value
mrb_hash_rassoc(mrb_state *mrb, mrb_value hash)
{
mrb_value key, value, has_key;
mrb_get_args(mrb, "o", &key);
has_key = mrb_hash_has_keyWithKey(mrb, hash, key);
if (mrb_test(has_key)) {
value = mrb_hash_get(mrb, hash, key);
return mrb_assoc_new(mrb, value, key);
}
else {
return mrb_nil_value();
}
}
/*
* call-seq:
* hash.flatten -> an_array
* hash.flatten(level) -> an_array
*
* Returns a new array that is a one-dimensional flattening of this
* hash. That is, for every key or value that is an array, extract
* its elements into the new array. Unlike Array#flatten, this
* method does not flatten recursively by default. The optional
* <i>level</i> argument determines the level of recursion to flatten.
*
* a = {1=> "one", 2 => [2,"two"], 3 => "three"}
* a.flatten # => [1, "one", 2, [2, "two"], 3, "three"]
* a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"]
*/
/*
* A <code>Hash</code> is a collection of key-value pairs. It is
* similar to an <code>Array</code>, except that indexing is done via
* arbitrary keys of any object type, not an integer index. Hashes enumerate
* their values in the order that the corresponding keys were inserted.
*
* Hashes have a <em>default value</em> that is returned when accessing
* keys that do not exist in the hash. By default, that value is
* <code>nil</code>.
*
*/
void
mrb_init_hash(mrb_state *mrb)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment