diff --git "a/C:\\Users\\LAZARI~1\\AppData\\Local\\Temp\\str8D7C.c" "b/P:\\ri\\sandbox\\rb193\\string.c" index 711918b..69c6486 100644 --- "a/C:\\Users\\LAZARI~1\\AppData\\Local\\Temp\\str8D7C.c" +++ "b/P:\\ri\\sandbox\\rb193\\string.c" @@ -406,10 +406,58 @@ str_new(VALUE klass, const char *ptr, long len) return str; } +/* use class-variable (bit-flag) */ +#define FL_CALL_INIT FL_USER18 + +VALUE +rb_str_method_added(VALUE self, VALUE method_symbol) +{ +/* callback method, called whenever a String class method is added (defined) */ + + ID mid = SYM2ID(method_symbol); + ID idInitialize = rb_intern("initialize"); + + if (mid == idInitialize) { + FL_SET(rb_cString, FL_CALL_INIT); + } + return Qtrue; /* unused */ +} + +VALUE +rb_str_method_undefined(VALUE self, VALUE method_symbol) +{ +/* callback method, called whenever a String class method is undefined */ + + if ( SYM2ID(method_symbol) == rb_intern("initialize") ) { + FL_UNSET(rb_cString, FL_CALL_INIT); + } + return Qtrue; /* unused */ +} + +VALUE +rb_str_method_removed(VALUE self, VALUE method_symbol) +{ +/* callback method, called whenever a String class method is removed */ + + if ( SYM2ID(method_symbol) == rb_intern("initialize") ) { + FL_UNSET(rb_cString, FL_CALL_INIT); + } + return Qtrue; /* unused */ +} + VALUE rb_str_new(const char *ptr, long len) { - return str_new(rb_cString, ptr, len); + /* str is already initialized by original initialize within str_new() */ + VALUE str = str_new(rb_cString, ptr, len); + + /* speed: call initialize only if it was redefined. See #4893 */ + if (FL_TEST(rb_cString, FL_CALL_INIT)) { + /* passing str itself as parameter, avoiding need for a temp str */ + rb_obj_call_init((VALUE)str, 1, &str); + } + + return str; } VALUE @@ -7724,6 +7772,11 @@ Init_String(void) rb_cString = rb_define_class("String", rb_cObject); rb_include_module(rb_cString, rb_mComparable); rb_define_alloc_func(rb_cString, str_alloc); + + rb_define_singleton_method(rb_cString, "method_added", rb_str_method_added, 1); + rb_define_singleton_method(rb_cString, "method_undefined", rb_str_method_undefined, 1); + rb_define_singleton_method(rb_cString, "method_removed", rb_str_method_removed, 1); + rb_define_singleton_method(rb_cString, "try_convert", rb_str_s_try_convert, 1); rb_define_method(rb_cString, "initialize", rb_str_init, -1); rb_define_method(rb_cString, "initialize_copy", rb_str_replace, 1);