summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2006-09-11 08:09:19 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2006-09-11 08:09:19 +0000
commitad0b87727df89ea54edb2d6a6b295147fbca55f8 (patch)
tree0377ff70716b13f971f94019c8078b2d5c86522b
parentf2ad09d5b7cdea64963433af13a9525bebc19a78 (diff)
* hash.c (rb_hash_identical): a new method to make a hash to
compare keys by their identity. * hash.c (rb_hash_identical_p): new method to tell if a hash is identical or not. * st.c (st_numcmp, st_numhash): export hash type functions. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10911 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog10
-rw-r--r--hash.c53
-rw-r--r--st.c14
-rw-r--r--st.h8
4 files changed, 70 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index abb1df4707..c84f86365c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Mon Sep 11 16:52:37 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * hash.c (rb_hash_identical): a new method to make a hash to
+ compare keys by their identity.
+
+ * hash.c (rb_hash_identical_p): new method to tell if a hash is
+ identical or not.
+
+ * st.c (st_numcmp, st_numhash): export hash type functions.
+
Mon Sep 11 11:42:21 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
* lib/rexml/source.rb (REXML::Source::encoding): should not
diff --git a/hash.c b/hash.c
index 10acf1487a..337007c39e 100644
--- a/hash.c
+++ b/hash.c
@@ -368,7 +368,7 @@ rb_hash_rehash(VALUE hash)
rb_raise(rb_eRuntimeError, "rehash during iteration");
}
rb_hash_modify(hash);
- tbl = st_init_table_with_size(&objhash, RHASH(hash)->tbl->num_entries);
+ tbl = st_init_table_with_size(RHASH(hash)->tbl->type, RHASH(hash)->tbl->num_entries);
rb_hash_foreach(hash, rb_hash_rehash_i, (st_data_t)tbl);
st_free_table(RHASH(hash)->tbl);
RHASH(hash)->tbl = tbl;
@@ -1475,6 +1475,54 @@ rb_hash_merge(VALUE hash1, VALUE hash2)
return rb_hash_update(rb_obj_dup(hash1), hash2);
}
+static struct st_hash_type identhash = {
+ st_numcmp,
+ st_numhash,
+};
+
+/*
+ * call-seq:
+ * hsh.identical => hsh
+ *
+ * Makes <i>hsh</i> to compare its keys by their identity, i.e. it
+ * will consider exact same objects as same keys.
+ *
+ * h1 = { "a" => 100, "b" => 200, :c => "c" }
+ * h1["a"] #=> "a"
+ * h1.identical
+ * h1.identical? #=> true
+ * h1["a"] #=> nil # different objects.
+ * h1[:c] #=> "c" # same symbols are all same.
+ *
+ */
+
+static VALUE
+rb_hash_identical(VALUE hash)
+{
+ rb_hash_modify(hash);
+ RHASH(hash)->tbl->type = &identhash;
+ rb_hash_rehash(hash);
+ return hash;
+}
+
+/*
+ * call-seq:
+ * hsh.identical? => true or false
+ *
+ * Returns <code>true</code> if <i>hsh</i> will compare its keys by
+ * their identity. Also see <code>Hash#identical</code>.
+ *
+ */
+
+static VALUE
+rb_hash_identical_p(VALUE hash)
+{
+ if (RHASH(hash)->tbl->type == &identhash) {
+ return Qtrue;
+ }
+ return Qfalse;
+}
+
static int path_tainted = -1;
static char **origenviron;
@@ -2324,6 +2372,9 @@ Init_Hash(void)
rb_define_method(rb_cHash,"key?", rb_hash_has_key, 1);
rb_define_method(rb_cHash,"value?", rb_hash_has_value, 1);
+ rb_define_method(rb_cHash,"identical", rb_hash_identical, 0);
+ rb_define_method(rb_cHash,"identical?", rb_hash_identical_p, 0);
+
#ifndef __MACOS__ /* environment variables nothing on MacOS. */
origenviron = environ;
envtbl = rb_obj_alloc(rb_cObject);
diff --git a/st.c b/st.c
index 0ace74e235..88d79f8d70 100644
--- a/st.c
+++ b/st.c
@@ -38,11 +38,9 @@ struct st_table_entry {
*
*/
-static int numcmp(long, long);
-static int numhash(long);
static struct st_hash_type type_numhash = {
- numcmp,
- numhash,
+ st_numcmp,
+ st_numhash,
};
/* extern int strcmp(const char *, const char *); */
@@ -589,14 +587,14 @@ strhash(register const char *string)
return hval;
}
-static int
-numcmp(long x, long y)
+int
+st_numcmp(long x, long y)
{
return x != y;
}
-static int
-numhash(long n)
+int
+st_numhash(long n)
{
return n;
}
diff --git a/st.h b/st.h
index 4dad9c5f04..45609ddeb1 100644
--- a/st.h
+++ b/st.h
@@ -60,11 +60,7 @@ void st_add_direct(st_table *, st_data_t, st_data_t);
void st_free_table(st_table *);
void st_cleanup_safe(st_table *, st_data_t);
st_table *st_copy(st_table *);
-
-#define ST_NUMCMP ((int (*)()) 0)
-#define ST_NUMHASH ((int (*)()) -2)
-
-#define st_numcmp ST_NUMCMP
-#define st_numhash ST_NUMHASH
+int st_numcmp(long, long);
+int st_numhash(long);
#endif /* ST_INCLUDED */