[#5218] Ruby Book Eng tl, ch1 question — Jon Babcock <jon@...>

13 messages 2000/10/02

[#5404] Object.foo, setters and so on — "Hal E. Fulton" <hal9000@...>

OK, here is what I think I know.

14 messages 2000/10/11

[#5425] Ruby Book Eng. tl, 9.8.11 -- seishitsu ? — Jon Babcock <jon@...>

18 messages 2000/10/11
[#5427] RE: Ruby Book Eng. tl, 9.8.11 -- seishitsu ? — OZAWA -Crouton- Sakuro <crouton@...> 2000/10/11

At Thu, 12 Oct 2000 03:49:46 +0900,

[#5429] Re: Ruby Book Eng. tl, 9.8.11 -- seishitsu ? — Jon Babcock <jon@...> 2000/10/11

Thanks for the input.

[#5432] Re: Ruby Book Eng. tl, 9.8.11 -- seishitsu ? — Yasushi Shoji <yashi@...> 2000/10/11

At Thu, 12 Oct 2000 04:53:41 +0900,

[#5516] Re: Some newbye question — ts <decoux@...>

>>>>> "D" == Davide Marchignoli <marchign@di.unipi.it> writes:

80 messages 2000/10/13
[#5531] Re: Some newbye question — matz@... (Yukihiro Matsumoto) 2000/10/14

Hi,

[#5544] Re: Some newbye question — Davide Marchignoli <marchign@...> 2000/10/15

On Sat, 14 Oct 2000, Yukihiro Matsumoto wrote:

[#5576] Re: local variables (nested, in-block, parameters, etc.) — Dave Thomas <Dave@...> 2000/10/16

matz@zetabits.com (Yukihiro Matsumoto) writes:

[#5617] Re: local variables (nested, in-block, parameters, etc.) — "Brian F. Feldman" <green@...> 2000/10/16

Dave Thomas <Dave@thomases.com> wrote:

[#5705] Dynamic languages, SWOT ? — Hugh Sasse Staff Elec Eng <hgs@...>

There has been discussion on this list/group from time to time about

16 messages 2000/10/20
[#5712] Re: Dynamic languages, SWOT ? — Charles Hixson <charleshixsn@...> 2000/10/20

Hugh Sasse Staff Elec Eng wrote:

[#5882] [RFC] Towards a new synchronisation primitive — hipster <hipster@...4all.nl>

Hello fellow rubyists,

21 messages 2000/10/26

[ruby-talk:5947] Hash.new {block} / Hash#default_proc{,_set}

From: "Brian F. Feldman" <green@...>
Date: 2000-10-30 16:47:09 UTC
List: ruby-talk #5947
I've done very little testing, but I think I've successfully implemented the 
ability for a Hash to provide a default procedure rather than variable.

The only reasonable way I could think of doing this required on-the-fly 
creation of a hash entry when a lookup fails -- otherwise, this feature is 
nearly useless (does not make anything easier).

Here's the diff, my 3rd time modifying Ruby code itself.  Comments?

--- ../ruby-1.6.2/hash.c	Tue Sep 12 01:37:23 2000
+++ ./hash.c	Sun Oct 29 22:43:48 2000
@@ -171,7 +171,7 @@
     NEWOBJ(hash, struct RHash);
     OBJSETUP(hash, klass, T_HASH);
 
-    hash->ifnone = Qnil;
+    hash->ifnone_proc = hash->ifnone = Qnil;
     hash->tbl = st_init_table(&objhash);
 
     return (VALUE)hash;
@@ -201,10 +201,11 @@
     VALUE *argv;
     VALUE hash;
 {
-    VALUE ifnone;
+    VALUE ifnone, ifnone_proc;
 
-    rb_scan_args(argc, argv, "01", &ifnone);
+    rb_scan_args(argc, argv, "01&", &ifnone, &ifnone_proc);
     rb_hash_modify(hash);
+    RHASH(hash)->ifnone_proc = ifnone_proc;
     RHASH(hash)->ifnone = ifnone;
 
     return hash;
@@ -223,7 +224,7 @@
 	NEWOBJ(hash, struct RHash);
 	OBJSETUP(hash, klass, T_HASH);
 	    
-	hash->ifnone = Qnil;
+	hash->ifnone_proc = hash->ifnone = Qnil;
 	hash->tbl = st_copy(RHASH(argv[0])->tbl);
 
 	return (VALUE)hash;
@@ -248,6 +249,7 @@
     NEWOBJ(clone, struct RHash);
     CLONESETUP(clone, hash);
 
+    clone->ifnone_proc = RHASH(hash)->ifnone_proc;
     clone->ifnone = RHASH(hash)->ifnone;
     clone->tbl = (st_table*)st_copy(RHASH(hash)->tbl);
 
@@ -284,6 +286,15 @@
     return hash;
 }
 
+static VALUE
+rb_hash_get_default(hash)
+    VALUE hash;
+{
+    if (RHASH(hash)->ifnone_proc != Qnil)
+	return rb_funcall(RHASH(hash)->ifnone_proc, rb_intern("call"), 0);
+    return RHASH(hash)->ifnone;
+}
+
 VALUE
 rb_hash_aref(hash, key)
     VALUE hash, key;
@@ -291,7 +302,9 @@
     VALUE val;
 
     if (!st_lookup(RHASH(hash)->tbl, key, &val)) {
-	return RHASH(hash)->ifnone;
+	if (RHASH(hash)->ifnone_proc != Qnil)
+	    return rb_hash_aset(hash, key, rb_hash_get_default(hash));
+	return rb_hash_get_default(hash);
     }
     return val;
 }
@@ -330,6 +343,13 @@
 }
 
 static VALUE
+rb_hash_default_proc(hash)
+    VALUE hash;
+{
+    return RHASH(hash)->ifnone_proc;
+}
+
+static VALUE
 rb_hash_set_default(hash, ifnone)
     VALUE hash, ifnone;
 {
@@ -337,6 +357,14 @@
     return hash;
 }
 
+static VALUE
+rb_hash_set_default_proc(hash)
+    VALUE hash;
+{
+    RHASH(hash)->ifnone_proc = rb_f_lambda();
+    return hash;
+}
+
 static int
 index_i(key, value, args)
     VALUE key, value;
@@ -356,7 +384,7 @@
     VALUE args[2];
 
     args[0] = value;
-    args[1] = RHASH(hash)->ifnone;
+    args[1] = rb_hash_get_default(hash);
 
     st_foreach(RHASH(hash)->tbl, index_i, args);
 
@@ -398,7 +426,7 @@
     if (rb_block_given_p()) {
 	return rb_yield(key);
     }
-    return RHASH(hash)->ifnone;
+    return rb_hash_get_default(hash);
 }
 
 struct shift_var {
@@ -430,7 +458,8 @@
     var.stop = 0;
     st_foreach(RHASH(hash)->tbl, shift_i, &var);
 
-    if (var.stop == 0) return RHASH(hash)->ifnone;
+    if (var.stop == 0)
+	return rb_hash_get_default(hash);
     return rb_assoc_new(var.key, var.val);
 }
 
@@ -1420,7 +1449,9 @@
     rb_define_method(rb_cHash,"fetch", rb_hash_fetch, -1);
     rb_define_method(rb_cHash,"[]=", rb_hash_aset, 2);
     rb_define_method(rb_cHash,"store", rb_hash_aset, 2);
+    rb_define_method(rb_cHash,"default_proc", rb_hash_default_proc, 0);
     rb_define_method(rb_cHash,"default", rb_hash_default, 0);
+    rb_define_method(rb_cHash,"default_proc_set", rb_hash_set_default_proc, 0);
     rb_define_method(rb_cHash,"default=", rb_hash_set_default, 1);
     rb_define_method(rb_cHash,"index", rb_hash_index, 1);
     rb_define_method(rb_cHash,"indexes", rb_hash_indexes, -1);
--- ../ruby-1.6.2/ruby.h	Mon Oct 16 01:04:05 2000
+++ ./ruby.h	Sun Oct 29 21:54:05 2000
@@ -273,6 +273,7 @@
     struct RBasic basic;
     struct st_table *tbl;
     int iter_lev;
+    VALUE ifnone_proc;
     VALUE ifnone;
 };
 


--
 Brian Fundakowski Feldman           \  FreeBSD: The Power to Serve!  /
 green@FreeBSD.org                    `------------------------------'



In This Thread

Prev Next