Yukihiro Matsumoto wrote:
> Interesting.

That's my cue! *hacks away some more*

> Probably.  If you will come up with the solution, I will consider it
> to be merged.  I'm too busy these days to provide the solution by
> myself.  Sorry.

Not a finished solution yet, but I have something that does seem to
work. It hasn't been tested much, but here are the diffs I have so far,
just in case someone else want this. (These are diffs towards the 1.6.5
release)


-------8<----------- [ cut here ] -------8<----------- 

*** ../../ruby-1.6.5/eval.c	Mon Sep 17 23:47:02 2001
--- eval.c	Fri Dec  7 19:55:14 2001
***************
*** 5266,5271 ****
--- 5266,5330 ----
  static VALUE rb_features;
  static st_table *loading_tbl;
  
+ /* deferred static extension initialization hack */
+ static VALUE rb_static_ext_hash;
+ static VALUE rb_mStaticExt, rb_cStaticExt;
+ typedef struct {
+   char * filename;
+   int required;
+   void (*initfunc)(void);
+ } rb_static_ext_entry;
+ 
+ void rb_static_ext_register( fname, initfunc )
+      char * fname ;
+      void (*initfunc)(void) ;
+ {
+   rb_static_ext_entry *p;
+   VALUE key, entry;
+ 
+   /* register a static extension in our map */
+   p = ALLOC( rb_static_ext_entry );
+   p->filename = fname;
+   p->initfunc = initfunc;
+   p->required = 0;
+   key = rb_str_new2( fname );
+   entry = Data_Wrap_Struct( rb_cStaticExt, 0,free, p );
+   rb_hash_aset( rb_static_ext_hash, key, entry );
+ }
+ 
+ 
+ int rb_static_ext_require( VALUE string )
+ {
+   VALUE ext;
+   rb_static_ext_entry *p;
+ 
+   ext = rb_hash_aref( rb_static_ext_hash, string );
+   if( NIL_P(ext) )
+     return -1;
+   
+   p = NULL;
+   Data_Get_Struct( ext,  rb_static_ext_entry, p );
+   if( p ){
+     if( ! p->required ){
+       /* we found the given string, and it isn't already required */
+       p->required = 1;
+       (*(p->initfunc))();
+       rb_provide( p->filename );
+       return 1;
+     }
+     else
+     {
+       /* already required */
+       return 0;
+     };
+   };
+   /* not found in our static_ext hash, please don't mind us */
+   return -1;
+ }
+ 
+ 
+ 
+ 
  static int
  rb_feature_p(feature, wait)
      const char *feature;
***************
*** 5356,5361 ****
--- 5415,5421 ----
      volatile VALUE load;
      int state;
      volatile int safe = ruby_safe_level;
+     int resultcode;
  
      Check_SafeStr(fname);
      ext = strrchr(RSTRING(fname)->ptr, '.');
***************
*** 5369,5374 ****
--- 5429,5439 ----
  	    }
  	}
  	else if (strcmp(".so", ext) == 0 || strcmp(".o", ext) == 0) {
+ 	  resultcode = rb_static_ext_require( fname );
+ 	  if( resultcode >= 0 ){
+ 	    return ( resultcode ? Qtrue : Qfalse );
+ 	  }
+ 
  	    fname = rb_str_new(RSTRING(fname)->ptr, ext-RSTRING(fname)->ptr);
  #ifdef DLEXT2
  	    tmp = fname;
***************
*** 6008,6013 ****
--- 6073,6084 ----
  
      rb_features = rb_ary_new();
      rb_define_readonly_variable("$\"", &rb_features);
+ 
+     // deferred static extension initialization stuff
+     rb_static_ext_hash = rb_hash_new();
+     rb_mStaticExt = rb_define_module("StaticExt");
+     rb_cStaticExt = rb_define_class_under( rb_mStaticExt, "Extention",
+ 					   rb_cObject );
  
      rb_define_global_function("load", rb_f_load, -1);
      rb_define_global_function("require", rb_f_require, 1);


-------8<----------- [ cut here ] -------8<----------- 

*** ../../ruby-1.6.5/ext/extmk.rb.in	Fri Jul 27 04:52:19 2001
--- ext/extmk.rb.in	Fri Dec  7 19:10:02 2001
***************
*** 720,725 ****
--- 720,726 ----
    exit
  end
  $extinit = "" unless $extinit
+ $extdefinitions = "" unless $extdefinitions 
  
  ruby = "@RUBY_INSTALL_NAME@@EXEEXT@"
  miniruby = "miniruby@EXEEXT@"
***************
*** 729,738 ****
    for s,t in $extlist
      f = format("%s/%s.%s", s, t, $LIBEXT)
      if File.exist?(f)
!       $extinit += format("\
! \tInit_%s();\n\
! \trb_provide(\"%s.so\");\n\
! ", t, s)
        $extobjs += "ext/"
        $extobjs += f
        $extobjs += " "
--- 730,743 ----
    for s,t in $extlist
      f = format("%s/%s.%s", s, t, $LIBEXT)
      if File.exist?(f)
!       #$extinit += format("\
! #\tInit_%s();\n\
! #\trb_provide(\"%s.so\");\n\
! #", t, s)
! 
!       $extinit +=format("\trb_static_ext_register( \"%s.so\", &Init_%s
);\n",s,t)
! 
!       $extdefinitions += format("void Init_%s(void);\n", t)
        $extobjs += "ext/"
        $extobjs += f
        $extobjs += " "
***************
*** 743,748 ****
--- 748,754 ----
  
    if older("extinit.c", "#{$top_srcdir}/ext/@setup@")
      f = open("extinit.c", "w")
+     f.printf $extdefinitions
      f.printf "void Init_ext() {\n"
      f.printf $extinit
      f.printf "}\n"

-------8<----------- [ cut here ] -------8<----------- 

I had some changes in intern.h too, but it compiled without that, so I
left it out.

-- 
<[ Kent Dahl ]>================<[ http://www.stud.ntnu.no/~kentda/ ]>
  )____(stud.techn.;ind.шл.data)||(softwareDeveloper.at(Trustix))_( 
 /"Opinions expressed are mine and not those of my Employer,      "\
( "the University, my girlfriend, stray cats, banana fruitflies,  " )
 \"nor the frontal lobe of my left cerebral hemisphere.           "/