[#26488] Add Standard Deviation Function to Math Module — Daniel Cohen <danielc2017@...>

This patch adds a Standard Deviation function to the Math Module. It takes

25 messages 2009/11/02
[#26489] Re: Add Standard Deviation Function to Math Module — Yukihiro Matsumoto <matz@...> 2009/11/03

Hi,

[#26490] Re: Add Standard Deviation Function to Math Module — Daniel Cohen <danielc2017@...> 2009/11/03

OK,

[#26493] Re: Add Standard Deviation Function to Math Module — Yukihiro Matsumoto <matz@...> 2009/11/03

Hi,

[#26511] Re: Add Standard Deviation Function to Math Module — Yusuke ENDOH <mame@...> 2009/11/03

Hi,

[#26492] HashWithIndifferentAccess to core — Urabe Shyouhei <shyouhei@...>

Hello,

35 messages 2009/11/03
[#26496] Re: HashWithIndifferentAccess to core — Yukihiro Matsumoto <matz@...> 2009/11/03

Hi,

[#26507] Re: HashWithIndifferentAccess to core — Jeremy Kemper <jeremy@...> 2009/11/03

On Tue, Nov 3, 2009 at 6:48 AM, Yukihiro Matsumoto <matz@ruby-lang.org> wro=

[#26514] Re: HashWithIndifferentAccess to core — "Martin J. Dst" <duerst@...> 2009/11/04

Just a thought: What about implementing this with an option on Hash:new,

[#26522] Re: HashWithIndifferentAccess to core — Yusuke ENDOH <mame@...> 2009/11/04

Hi,

[#26555] Re: HashWithIndifferentAccess to core — Yukihiro Matsumoto <matz@...> 2009/11/05

Hi,

[#26584] Re: HashWithIndifferentAccess to core — Yugui <yugui@...> 2009/11/07

2009/11/6 Yukihiro Matsumoto <matz@ruby-lang.org>:

[#26589] Re: HashWithIndifferentAccess to core — Yukihiro Matsumoto <matz@...> 2009/11/07

Hi,

[#26593] Re: HashWithIndifferentAccess to core — Lourens Naud<lourens@...> 2009/11/07

Hi,

[#26523] [Bug #2330] Non systematic segmentation fault with autoload rubyspec — Marc-Andre Lafortune <redmine@...>

Bug #2330: Non systematic segmentation fault with autoload rubyspec

12 messages 2009/11/04

[#26560] [Feature #2340] Removing YAML/Syck — Yui NARUSE <redmine@...>

Feature #2340: Removing YAML/Syck

38 messages 2009/11/06
[#26562] [Feature #2340] Removing YAML/Syck — Yui NARUSE <redmine@...> 2009/11/06

Issue #2340 has been updated by Yui NARUSE.

[#26567] Re: [Feature #2340] Removing YAML/Syck — James Edward Gray II <james@...> 2009/11/06

On Nov 6, 2009, at 4:02 AM, Yui NARUSE wrote:

[#26568] Re: [Feature #2340] Removing YAML/Syck — Jon <jon.forums@...> 2009/11/06

> > Issue #2340 has been updated by Yui NARUSE.

[#26571] Re: [Feature #2340] Removing YAML/Syck — "NARUSE, Yui" <naruse@...> 2009/11/06

Jon wrote:

[#26574] Re: [Feature #2340] Removing YAML/Syck — Aaron Patterson <aaron@...> 2009/11/06

On Sat, Nov 07, 2009 at 12:59:25AM +0900, NARUSE, Yui wrote:

[#26635] [Feature #2348] RBTree Should be Added to the Standard Library — James Gray <redmine@...>

Feature #2348: RBTree Should be Added to the Standard Library

20 messages 2009/11/08
[#28842] [Feature #2348] RBTree Should be Added to the Standard Library — James Gray <redmine@...> 2010/03/21

Issue #2348 has been updated by James Gray.

[#26650] [Feature #2350] Unicode specific functionality on String in 1.9 — Manfred Stienstra <redmine@...>

Feature #2350: Unicode specific functionality on String in 1.9

12 messages 2009/11/09
[#28985] [Feature #2350](Rejected) Unicode specific functionality on String in 1.9 — Yusuke Endoh <redmine@...> 2010/03/25

Issue #2350 has been updated by Yusuke Endoh.

[#28993] Re: [Feature #2350](Rejected) Unicode specific functionality on String in 1.9 — Nikolai Weibull <now@...> 2010/03/25

On Thu, Mar 25, 2010 at 14:45, Yusuke Endoh <redmine@ruby-lang.org> wrote:

[#26704] Maintainer confirmation process done. — "Yugui (Yuki Sonoda)" <yugui@...>

I'm sorry for my closing the maintainer confirmation process so late.

13 messages 2009/11/12

[#26736] [Bug #2365] Matrix: poor handling of coercion errors [patch] — Marc-Andre Lafortune <redmine@...>

Bug #2365: Matrix: poor handling of coercion errors [patch]

12 messages 2009/11/14

[#26772] [Bug #2378] Regression in ParseDate.parsedate('nn-nn') — Vladimir Sizikov <redmine@...>

Bug #2378: Regression in ParseDate.parsedate('nn-nn')

10 messages 2009/11/16

[#26774] Ruby constant lookup — Yehuda Katz <wycats@...>

Over the past six months or so, I have been working with the new Ruby 1.9

22 messages 2009/11/16
[#26775] Re: Ruby constant lookup — Shugo Maeda <shugo@...> 2009/11/17

Hi,

[#26777] Re: Ruby constant lookup — Yehuda Katz <wycats@...> 2009/11/17

Shugo,

[#26778] Re: Ruby constant lookup — Shugo Maeda <shugo@...> 2009/11/17

Hi,

[#26869] Caching #to_s for immutables (and a possible future for constant-folding) — Kurt Stephens <ks@...>

I have a proof-of-concept patch to MRI that caches #to_s values for

16 messages 2009/11/23
[#26936] Re: Caching #to_s for immutables (and a possible future for constant-folding) — Roger Pack <rogerdpack@...> 2009/11/29

> =A0It reduces the number of #to_s Strings created during the MRI test sui=

[#26958] Re: Caching #to_s for immutables (and a possible future for constant-folding) [with patch] — Kurt Stephens <ks@...> 2009/11/30

The attached patch add caching of #to_s results to the main immutable

[#26960] Re: Caching #to_s for immutables (and a possible future for constant-folding) [with patch] — Roger Pack <rogerdpack@...> 2009/11/30

> Yes. =A0The MRI test suite runs at 45 sec with these changes and at 53 se=

[#26963] Re: Caching #to_s for immutables (and a possible future for constant-folding) [with patch] — Kurt Stephens <ks@...> 2009/11/30

I just ran rubyspec against it; ~ 5% time improvement.

[ruby-core:26625] Re: HashWithIndifferentAccess to core

From: Nobuyoshi Nakada <nobu@...>
Date: 2009-11-08 15:06:51 UTC
List: ruby-core #26625
Hi,

At Sun, 8 Nov 2009 12:25:54 +0900,
Yusuke ENDOH wrote in [ruby-core:26612]:
> > I've been toying with allowing custom hashing from the Ruby side for the
> > past 2 days and have a semi-functional version (patch attached against
> > subversion trunk 25671 - http://gist.github.com/228773)
> 
> Unfortunately, your patch has a serious problem; it lets RHash have
> four VALUEs, which makes any object require 24 bytes (traditionally
> 20 bytes) in 32 bit envirionment.

I don't think that index_with object is necessary, why the hash
itself can't have such methods?


Index: hash.c
===================================================================
--- hash.c	(revision 25690)
+++ hash.c	(working copy)
@@ -24,4 +24,6 @@ static VALUE rb_hash_s_try_convert(VALUE
 #define HASH_DELETED  FL_USER1
 #define HASH_PROC_DEFAULT FL_USER2
+#define HASH_PERMANET HASH_PROC_DEFAULT
+#define RHASH_CUSTOM_P(h) (RHASH(h)->ntbl && RHASH(h)->ntbl->extended)
 
 VALUE
@@ -34,5 +36,5 @@ VALUE rb_cHash;
 
 static VALUE envtbl;
-static ID id_hash, id_yield, id_default;
+static ID id_hash, id_yield, id_default, id_key_filter, id_custom_compare, id_custom_hash;
 
 static int
@@ -110,4 +112,24 @@ static const struct st_hash_type identha
 };
 
+static VALUE
+rb_hash_custom_key(VALUE hash, VALUE key)
+{
+    if (RHASH_CUSTOM_P(hash)) {
+	VALUE newkey = rb_check_funcall(hash, id_key_filter, 1, &key);
+	if (newkey != Qundef) key = newkey;
+    }
+    return key;
+}
+
+static VALUE
+hash_lookup(VALUE hash, VALUE *key, VALUE *val)
+{
+    st_data_t data;
+    *key = rb_hash_custom_key(hash, *key);
+    if (!st_lookup(RHASH(hash)->ntbl, (st_data_t)*key, &data)) return FALSE;
+    if (val) *val = (VALUE)data;
+    return TRUE;
+}
+
 typedef int st_foreach_func(st_data_t, st_data_t, st_data_t);
 
@@ -494,5 +516,5 @@ rb_hash_aref(VALUE hash, VALUE key)
     VALUE val;
 
-    if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
+    if (!RHASH(hash)->ntbl || !hash_lookup(hash, &key, &val)) {
 	return rb_funcall(hash, id_default, 1, key);
     }
@@ -505,5 +527,5 @@ rb_hash_lookup2(VALUE hash, VALUE key, V
     VALUE val;
 
-    if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
+    if (!RHASH(hash)->ntbl || !hash_lookup(hash, &key, &val)) {
 	return def; /* without Hash#default */
     }
@@ -559,5 +581,5 @@ rb_hash_fetch_m(int argc, VALUE *argv, V
 	rb_warn("block supersedes default value argument");
     }
-    if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
+    if (!RHASH(hash)->ntbl || !hash_lookup(hash, &key, &val)) {
 	if (block_given) return rb_yield(key);
 	if (argc == 1) {
@@ -1406,5 +1428,5 @@ rb_hash_has_key(VALUE hash, VALUE key)
     if (!RHASH(hash)->ntbl)
         return Qfalse;
-    if (st_lookup(RHASH(hash)->ntbl, key, 0)) {
+    if (hash_lookup(hash, &key, 0)) {
 	return Qtrue;
     }
@@ -1452,4 +1474,5 @@ struct equal_data {
     VALUE result;
     st_table *tbl;
+    VALUE custom;
     int eql;
 };
@@ -1462,4 +1485,8 @@ eql_i(VALUE key, VALUE val1, VALUE arg)
 
     if (key == Qundef) return ST_CONTINUE;
+    if (data->custom != Qundef) {
+	VALUE newkey = rb_check_funcall(data->custom, id_key_filter, 1, &key);
+	if (newkey != Qundef) key = newkey;
+    }
     if (!st_lookup(data->tbl, key, &val2)) {
 	data->result = Qfalse;
@@ -1514,4 +1541,5 @@ hash_equal(VALUE hash1, VALUE hash2, int
 
     data.tbl = RHASH(hash2)->ntbl;
+    data.custom = hash2;
     data.eql = eql;
     return rb_exec_recursive_paired(recursive_eql, hash1, hash2, (VALUE)&data);
@@ -1854,4 +1882,49 @@ rb_hash_compare_by_id_p(VALUE hash)
 }
 
+static int
+rb_hash_custom_compare(st_data_t a, st_data_t b, st_data_t hash)
+{
+    VALUE args[2], c;
+    args[0] = (VALUE)a;
+    args[1] = (VALUE)b;
+    c = rb_check_funcall((VALUE)hash, id_custom_compare, 2, args);
+    if (c == Qundef) return rb_any_cmp((VALUE)a, (VALUE)b);
+    return rb_cmpint(c, (VALUE)a, (VALUE)b);
+}
+
+static st_index_t
+rb_hash_custom_hash(st_data_t a, st_data_t hash)
+{
+    VALUE args[1], c;
+    args[0] = (VALUE)a;
+    c = rb_check_funcall((VALUE)hash, id_custom_hash, 1, args);
+    if (c == Qundef) return rb_any_hash((VALUE)a);
+    return NUM2ULONG(c);
+}
+
+static const struct st_hash_type customhash = {
+    rb_hash_custom_compare,
+    rb_hash_custom_hash,
+};
+
+VALUE
+rb_hash_customized_p(VALUE hash)
+{
+    return RHASH_CUSTOM_P(hash) ? Qtrue : Qfalse;
+}
+
+VALUE
+rb_hash_customize(VALUE hash)
+{
+    st_table *tbl = RHASH(hash)->ntbl;
+    if (tbl) {
+	if (tbl->extended) return hash;
+	if (tbl->num_entries) rb_raise(rb_eArgError, "non-empty hash");
+	st_free_table(tbl);
+    }
+    RHASH(hash)->ntbl = st_init_extable(&customhash, (st_data_t)hash);
+    return hash;
+}
+
 static int path_tainted = -1;
 
@@ -2649,4 +2722,7 @@ Init_Hash(void)
     id_yield = rb_intern("yield");
     id_default = rb_intern("default");
+    id_key_filter = rb_intern("key_filter");
+    id_custom_compare = rb_intern("custom_compare");
+    id_custom_hash = rb_intern("custom_hash");
 
     rb_cHash = rb_define_class("Hash", rb_cObject);
@@ -2717,4 +2793,6 @@ Init_Hash(void)
     rb_define_method(rb_cHash,"compare_by_identity", rb_hash_compare_by_id, 0);
     rb_define_method(rb_cHash,"compare_by_identity?", rb_hash_compare_by_id_p, 0);
+    rb_define_method(rb_cHash,"customized?", rb_hash_customized_p, 0);
+    rb_define_method(rb_cHash,"customize", rb_hash_customize, 0);
 
     origenviron = environ;
Index: st.c
===================================================================
--- st.c	(revision 25690)
+++ st.c	(working copy)
@@ -26,4 +26,9 @@ struct st_table_entry {
 };
 
+typedef struct st_extable {
+    struct st_table basic;
+    st_data_t data;
+} st_extable;
+
 #define ST_DEFAULT_MAX_DENSITY 5
 #define ST_DEFAULT_INIT_TABLE_SIZE 11
@@ -62,4 +67,5 @@ static void rehash(st_table *);
 #define malloc xmalloc
 #define calloc xcalloc
+#define realloc xrealloc
 #define free(x) xfree(x)
 #endif
@@ -70,8 +76,15 @@ static void rehash(st_table *);
 #define Calloc(n,s) (char*)calloc((n),(s))
 
-#define EQUAL(table,x,y) ((x)==(y) || (*table->type->compare)((x),(y)) == 0)
+#define extended_data(table) (((st_extable*)(table))->data)
+#define compare_basic(table,x,y) (*table->type->compare)((x),(y))
+#define compare_extended(table,x,y) (*table->type->compare)((x),(y),extended_data(table))
+#define do_compare(table,x,y) ((table)->extended ? compare_extended(table,x,y) : compare_basic(table,x,y))
+#define EQUAL(table,x,y) ((x)==(y) || do_compare(table,x,y) == 0)
 
 /* remove cast to unsigned int in the future */
-#define do_hash(key,table) (unsigned int)(st_index_t)(*(table)->type->hash)((key))
+#define hash_basic(key,table) (*(table)->type->hash)((key))
+#define hash_extended(key,table) (*(table)->type->hash)((key),extended_data(table))
+#define do_hash(key,table) (unsigned int)(st_index_t)\
+    ((table)->extended ? hash_extended(key,table) : hash_basic(key,table))
 #define do_hash_bin(key,table) (do_hash(key, table)%(table)->num_bins)
 
@@ -164,6 +177,6 @@ stat_col(void)
 #define MAX_PACKED_NUMHASH (ST_DEFAULT_INIT_TABLE_SIZE/2)
 
-st_table*
-st_init_table_with_size(const struct st_hash_type *type, st_index_t size)
+static st_table*
+init_table_with_size(size_t tblsize, const struct st_hash_type *type, st_index_t size)
 {
     st_table *tbl;
@@ -184,6 +197,7 @@ st_init_table_with_size(const struct st_
     size = new_size(size);	/* round up to prime number */
 
-    tbl = alloc(st_table);
+    tbl = malloc(tblsize);
     tbl->type = type;
+    tbl->extended = 0;
     tbl->num_entries = 0;
     tbl->entries_packed = type == &type_numhash && size/2 <= MAX_PACKED_NUMHASH;
@@ -197,4 +211,10 @@ st_init_table_with_size(const struct st_
 
 st_table*
+st_init_table_with_size(const struct st_hash_type *type, st_index_t size)
+{
+    return init_table_with_size(sizeof(st_table), type, size);
+}
+
+st_table*
 st_init_table(const struct st_hash_type *type)
 {
@@ -238,4 +258,28 @@ st_init_strcasetable_with_size(st_index_
 }
 
+st_table*
+st_init_extable_with_size(const struct st_hash_type *type, st_data_t data, st_index_t size)
+{
+    st_table *tbl = init_table_with_size(sizeof(st_extable), type, size);
+    tbl->extended = 1;
+    extended_data(tbl) = data;
+    return tbl;
+}
+
+st_table*
+st_init_extable(const struct st_hash_type *type, st_data_t data)
+{
+    return st_init_extable_with_size(type, data, 0);
+}
+
+st_table *
+st_extend(st_table *table, const struct st_hash_type *type, st_data_t data)
+{
+    st_table *tbl = realloc(table, sizeof(st_extable));
+    tbl->extended = 1;
+    extended_data(tbl) = data;
+    return tbl;
+}
+
 void
 st_clear(st_table *table)
@@ -563,5 +607,5 @@ st_copy(st_table *old_table)
     st_index_t hash_val;
 
-    new_table = alloc(st_table);
+    new_table = malloc(old_table->extended ? sizeof(st_table) : sizeof(st_extable));
     if (new_table == 0) {
 	return 0;
Index: include/ruby/st.h
===================================================================
--- include/ruby/st.h	(revision 25690)
+++ include/ruby/st.h	(working copy)
@@ -79,5 +79,9 @@ struct st_hash_type {
 struct st_table {
     const struct st_hash_type *type;
-    st_index_t num_bins;
+    unsigned int extended : 1;
+#ifdef __GNUC__
+    __extension__
+#endif
+    st_index_t num_bins : ST_INDEX_BITS - 1;
     unsigned int entries_packed : 1;
 #ifdef __GNUC__
@@ -101,4 +105,7 @@ st_table *st_init_strtable_with_size(st_
 st_table *st_init_strcasetable(void);
 st_table *st_init_strcasetable_with_size(st_index_t);
+st_table *st_init_extable(const struct st_hash_type *, st_data_t);
+st_table *st_init_extable_with_size(const struct st_hash_type *, st_data_t, st_index_t);
+st_table *st_extend(st_table *, const struct st_hash_type *, st_data_t);
 int st_delete(st_table *, st_data_t *, st_data_t *); /* returns 0:notfound 1:deleted */
 int st_delete_safe(st_table *, st_data_t *, st_data_t *, st_data_t);
Index: test/ruby/test_hash.rb
===================================================================
--- test/ruby/test_hash.rb	(revision 25690)
+++ test/ruby/test_hash.rb	(working copy)
@@ -869,6 +869,44 @@ class TestHash < Test::Unit::TestCase
 
     o = Object.new
-    def o.hash; 2<<100; end
+    def o.hash; 2 << 100; end
     assert_equal({x=>1}.hash, {x=>1}.hash)
   end
+
+  class StringHash < Hash
+    def key_filter(key)
+      key.to_s
+    end
+    def initialize(*)
+      super.customize
+    end
+  end
+
+  class IdentHash < Hash
+    def custom_compare(a, b)
+      p [a,b]
+      a.object_id == b.object_id
+    end
+    def custom_hash(a)
+      a.object_id
+    end
+    def initialize(*)
+      super.customize
+    end
+  end
+
+  def test_stringhash
+    h = {"abc"=>"def"}
+    assert_nil(h[:abc])
+    s = StringHash.new.update(h)
+    assert_equal("def", s[:abc])
+  end
+
+  def test_identhash
+    a = "abc"
+    h = {a=>"def"}
+    assert_equal("def", h["abc"])
+    i = IdentHash.new.update(h)
+    assert_nil(i["abc"])
+    assert_equal("def", h[a])
+  end
 end


-- 
Nobu Nakada

In This Thread