aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--class.c24
-rw-r--r--include/ruby/intern.h2
-rw-r--r--struct.c21
-rw-r--r--test/ruby/test_struct.rb7
5 files changed, 46 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index 34ccc15de9..21bf2241d4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Wed Aug 12 15:32:16 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * class.c (rb_define_class_id_under, rb_define_module_id_under):
+ new functions to define a nested class/module with non-ascii
+ name.
+
+ * struct.c (make_struct): use name with encoding.
+
+ * struct.c (inspect_struct): ditto. [ruby-core:24849]
+
Wed Aug 12 Wed Aug 12 14:54:34 2009 Koichi Sasada <ko1@atdot.net>
* insns.def, vm.c, vm_insnhelper.c, vm_insnhelper.h: check
diff --git a/class.c b/class.c
index b04f00c549..93b696798d 100644
--- a/class.c
+++ b/class.c
@@ -359,26 +359,30 @@ rb_define_class(const char *name, VALUE super)
VALUE
rb_define_class_under(VALUE outer, const char *name, VALUE super)
{
+ return rb_define_class_id_under(outer, rb_intern(name), super);
+}
+
+VALUE
+rb_define_class_id_under(VALUE outer, ID id, VALUE super)
+{
VALUE klass;
- ID id;
- id = rb_intern(name);
if (rb_const_defined_at(outer, id)) {
klass = rb_const_get_at(outer, id);
if (TYPE(klass) != T_CLASS) {
- rb_raise(rb_eTypeError, "%s is not a class", name);
+ rb_raise(rb_eTypeError, "%s is not a class", rb_id2name(id));
}
if (rb_class_real(RCLASS_SUPER(klass)) != super) {
- rb_name_error(id, "%s is already defined", name);
+ rb_name_error(id, "%s is already defined", rb_id2name(id));
}
return klass;
}
if (!super) {
rb_warn("no super class for `%s::%s', Object assumed",
- rb_class2name(outer), name);
+ rb_class2name(outer), rb_id2name(id));
}
klass = rb_define_class_id(id, super);
- rb_set_class_path(klass, outer, name);
+ rb_set_class_path_string(klass, outer, rb_id2str(id));
rb_const_set(outer, id, klass);
rb_class_inherited(super, klass);
@@ -429,10 +433,14 @@ rb_define_module(const char *name)
VALUE
rb_define_module_under(VALUE outer, const char *name)
{
+ return rb_define_module_id_under(outer, rb_intern(name));
+}
+
+VALUE
+rb_define_module_under(VALUE outer, ID id)
+{
VALUE module;
- ID id;
- id = rb_intern(name);
if (rb_const_defined_at(outer, id)) {
module = rb_const_get_at(outer, id);
if (TYPE(module) == T_MODULE)
diff --git a/include/ruby/intern.h b/include/ruby/intern.h
index 570f80baaa..93a35563d4 100644
--- a/include/ruby/intern.h
+++ b/include/ruby/intern.h
@@ -152,8 +152,10 @@ VALUE rb_make_metaclass(VALUE, VALUE);
void rb_check_inheritable(VALUE);
VALUE rb_class_inherited(VALUE, VALUE);
VALUE rb_define_class_id(ID, VALUE);
+VALUE rb_define_class_id_under(VALUE, ID, VALUE);
VALUE rb_module_new(void);
VALUE rb_define_module_id(ID);
+VALUE rb_define_module_id_under(VALUE, ID);
VALUE rb_mod_included_modules(VALUE);
VALUE rb_mod_include_p(VALUE, VALUE);
VALUE rb_mod_ancestors(VALUE);
diff --git a/struct.c b/struct.c
index e4b6da0e76..e87dddae42 100644
--- a/struct.c
+++ b/struct.c
@@ -196,7 +196,7 @@ make_struct(VALUE name, VALUE members, VALUE klass)
rb_warn("redefining constant Struct::%s", StringValuePtr(name));
rb_mod_remove_const(klass, ID2SYM(id));
}
- nstr = rb_define_class_under(klass, rb_id2name(id), klass);
+ nstr = rb_define_class_id_under(klass, id, klass);
}
rb_ivar_set(nstr, id_members, members);
@@ -496,21 +496,19 @@ rb_struct_each_pair(VALUE s)
static VALUE
inspect_struct(VALUE s, VALUE dummy, int recur)
{
- const char *cname = rb_class2name(rb_obj_class(s));
- VALUE str, members;
+ VALUE cname = rb_class_name(rb_obj_class(s));
+ VALUE members, str = rb_str_new2("#<struct ");
long i;
+ char first = RSTRING_PTR(cname)[0];
+ if (recur || first != '#') {
+ rb_str_append(str, cname);
+ }
if (recur) {
- return rb_sprintf("#<struct %s:...>", cname);
+ return rb_str_cat2(str, ":...>");
}
members = rb_struct_members(s);
- if (cname[0] == '#') {
- str = rb_str_new2("#<struct ");
- }
- else {
- str = rb_sprintf("#<struct %s ", cname);
- }
for (i=0; i<RSTRUCT_LEN(s); i++) {
VALUE slot;
ID id;
@@ -518,6 +516,9 @@ inspect_struct(VALUE s, VALUE dummy, int recur)
if (i > 0) {
rb_str_cat2(str, ", ");
}
+ else if (first != '#') {
+ rb_str_cat2(str, " ");
+ }
slot = RARRAY_PTR(members)[i];
id = SYM2ID(slot);
if (rb_is_local_id(id) || rb_is_const_id(id)) {
diff --git a/test/ruby/test_struct.rb b/test/ruby/test_struct.rb
index 7be05c00d2..b6a77a9fb7 100644
--- a/test/ruby/test_struct.rb
+++ b/test/ruby/test_struct.rb
@@ -212,4 +212,11 @@ class TestStruct < Test::Unit::TestCase
Struct.new(0)
}
end
+
+ def test_nonascii
+ struct_test = Struct.new("R\u{e9}sum\u{e9}", :"r\u{e9}sum\u{e9}")
+ assert_equal(Struct.const_get("R\u{e9}sum\u{e9}"), struct_test, '[ruby-core:24849]')
+ a = struct_test.new(42)
+ assert_equal("#<struct Struct::R\u{e9}sum\u{e9} r\u{e9}sum\u{e9}=42>", a.inspect, '[ruby-core:24849]')
+ end
end