From: "Ara.T.Howard" Date: 2005-05-23T00:13:01+09:00 Subject: Re: join not in Enumerable On Sun, 22 May 2005 nobu.nokada@softhome.net wrote: > Hi, > > At Sun, 22 May 2005 08:56:08 +0900, > Ara.T.Howard wrote in [ruby-talk:143311]: >> the only reason i can think of is that just because somthing is countable >> (Enumerable) doesn't mean each sub-thing is singular. take a hash for >> example. this is no stubling block (pun intended) for ruby however: > > Feels interesting. > > > Index: enum.c > =================================================================== > RCS file: /cvs/ruby/src/ruby/enum.c,v > retrieving revision 1.54 > diff -U2 -p -r1.54 enum.c > --- enum.c 30 Oct 2004 06:56:17 -0000 1.54 > +++ enum.c 22 May 2005 09:36:21 -0000 > @@ -967,4 +967,52 @@ enum_zip(argc, argv, obj) > } > > +static VALUE > +enum_join_s(obj, arg, recur) > + VALUE obj, *arg; > + int recur; > +{ > + if (recur) { > + static const char recursed[] = "[...]"; > + if (!NIL_P(arg[1]) && RSTRING(arg[0])->len != 0) { > + rb_str_append(arg[0], arg[1]); > + } > + rb_str_cat(arg[0], recursed, sizeof(recursed) - 1); > + } > + else { > + if (rb_block_given_p()) { > + obj = rb_yield(obj); > + } > + if (TYPE(obj) != T_STRING) { > + obj = rb_obj_as_string(obj); > + } > + if (!NIL_P(arg[1]) && RSTRING(arg[0])->len != 0) { > + rb_str_append(arg[0], arg[1]); > + } > + rb_str_append(arg[0], obj); > + } > + return arg[0]; > +} > + > +static VALUE > +enum_join_i(el, arg) > + VALUE el, arg; > +{ > + return rb_exec_recursive(enum_join_s, el, arg); > +} > + > +static VALUE > +enum_join(argc, argv, obj) > + int argc; > + VALUE *argv; > + VALUE obj; > +{ > + VALUE arg[2]; > + > + rb_scan_args(argc, argv, "01", &arg[1]); > + arg[0] = rb_str_new(0, 0); > + rb_iterate(rb_each, obj, enum_join_i, (VALUE)arg); > + return arg[0]; > +} > + > /* > * The Enumerable mixin provides collection classes with > @@ -998,4 +1046,5 @@ Init_Enumerable() > rb_define_method(rb_mEnumerable,"inject", enum_inject, -1); > rb_define_method(rb_mEnumerable,"partition", enum_partition, 0); > + rb_define_method(rb_mEnumerable,"classify", enum_classify, 0); > rb_define_method(rb_mEnumerable,"all?", enum_all, 0); > rb_define_method(rb_mEnumerable,"any?", enum_any, 0); > @@ -1008,4 +1057,5 @@ Init_Enumerable() > rb_define_method(rb_mEnumerable,"each_with_index", enum_each_with_index, 0); > rb_define_method(rb_mEnumerable, "zip", enum_zip, -1); > + rb_define_method(rb_mEnumerable, "join", enum_join, -1); > > id_eqq = rb_intern("==="); only you would crank that out in C nobu ;-) looks good for enumerable: harp:~/build/ruby > ./ruby -e' p( {:k => :v, :K => :V }.join(","){|kv| kv.join "=>"} ) ' "k=>v,K=>V" but doesn't override Array's current behaviour: harp:~/build/ruby > ./ruby -e'a3 = [ [ [4], [2] ], [ ["forty"], ["two"] ] ]; p a3.join("___"){|a2| a2.join("__"){|a1| a1.join "_"}}' "4___2___forty___two" i'm not sure how to do this in C: module Enumerable def join(sep = '', &b) inject(nil){|s,x| "#{ s }#{ s && sep }#{ b ? b[ x ] : x }"} end end class Array def join(*a, &b); super; end end so Array's join is clobbered... kind regards. -a -- =============================================================================== | email :: ara [dot] t [dot] howard [at] noaa [dot] gov | phone :: 303.497.6469 | My religion is very simple. My religion is kindness. | --Tenzin Gyatso ===============================================================================