From 5da55dfcb480ab2c3a5c2162ee004b155c198099 Mon Sep 17 00:00:00 2001 From: ko1 Date: Thu, 29 Aug 2013 09:12:25 +0000 Subject: [PATCH] * struct.c (rb_struct_define_without_accessor_under): added. This function is similar to rb_define_class_under() against rb_define_class(). * include/ruby/intern.h: add a declaration of this function. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42725 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 8 ++++++ include/ruby/intern.h | 2 ++ struct.c | 62 ++++++++++++++++++++++++++++++++----------- 3 files changed, 57 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index d7521882d0..a7683a09e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Thu Aug 29 18:05:33 2013 Koichi Sasada + + * struct.c (rb_struct_define_without_accessor_under): added. + This function is similar to rb_define_class_under() against + rb_define_class(). + + * include/ruby/intern.h: add a declaration of this function. + Thu Aug 29 17:03:10 2013 Nobuyoshi Nakada * vm_insnhelper.c (vm_call_method): a method entry refers the based diff --git a/include/ruby/intern.h b/include/ruby/intern.h index e8821acda4..5581c05925 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -848,6 +848,8 @@ VALUE rb_struct_s_members(VALUE); VALUE rb_struct_members(VALUE); VALUE rb_struct_alloc_noinit(VALUE); VALUE rb_struct_define_without_accessor(const char *, VALUE, rb_alloc_func_t, ...); +VALUE rb_struct_define_without_accessor_under(VALUE outer, const char *class_name, VALUE super, rb_alloc_func_t alloc, ...); + /* thread.c */ typedef void rb_unblock_function_t(void *); typedef VALUE rb_blocking_function_t(void *); diff --git a/struct.c b/struct.c index bd1d0d04fe..f7c61c73ec 100644 --- a/struct.c +++ b/struct.c @@ -229,10 +229,38 @@ rb_struct_alloc_noinit(VALUE klass) return struct_alloc(klass); } -VALUE -rb_struct_define_without_accessor(const char *class_name, VALUE super, rb_alloc_func_t alloc, ...) +static VALUE +struct_define_without_accessor(VALUE outer, const char *class_name, VALUE super, rb_alloc_func_t alloc, VALUE members) { VALUE klass; + + if (class_name) { + if (outer) { + klass = rb_define_class_under(outer, class_name, super); + } + else { + klass = rb_define_class(class_name, super); + } + } + else { + klass = anonymous_struct(super); + } + + rb_ivar_set(klass, id_members, members); + + if (alloc) { + rb_define_alloc_func(klass, alloc); + } + else { + rb_define_alloc_func(klass, struct_alloc); + } + + return klass; +} + +VALUE +rb_struct_define_without_accessor_under(VALUE outer, const char *class_name, VALUE super, rb_alloc_func_t alloc, ...) +{ va_list ar; VALUE members; char *name; @@ -245,21 +273,25 @@ rb_struct_define_without_accessor(const char *class_name, VALUE super, rb_alloc_ va_end(ar); OBJ_FREEZE(members); - if (class_name) { - klass = rb_define_class(class_name, super); - } - else { - klass = anonymous_struct(super); + return struct_define_without_accessor(outer, class_name, super, alloc, members); +} + +VALUE +rb_struct_define_without_accessor(const char *class_name, VALUE super, rb_alloc_func_t alloc, ...) +{ + va_list ar; + VALUE members; + char *name; + + members = rb_ary_tmp_new(0); + va_start(ar, alloc); + while ((name = va_arg(ar, char*)) != NULL) { + rb_ary_push(members, ID2SYM(rb_intern(name))); } + va_end(ar); + OBJ_FREEZE(members); - rb_ivar_set(klass, id_members, members); - - if (alloc) - rb_define_alloc_func(klass, alloc); - else - rb_define_alloc_func(klass, struct_alloc); - - return klass; + return struct_define_without_accessor(0, class_name, super, alloc, members); } VALUE