aboutsummaryrefslogtreecommitdiffstats
path: root/struct.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-11-16 09:21:56 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-11-16 09:21:56 +0000
commit20690026a7dd7622c7d824de71e337a68a293b63 (patch)
treec2e21553dc5527199a6caac0588ffb158d9be7dd /struct.c
parent1ff30ea2b1675fa6bfa50bb5bac1f8cdea8524e1 (diff)
downloadruby-20690026a7dd7622c7d824de71e337a68a293b63.tar.gz
struct.c: dig
* object.c (rb_obj_dig): dig in nested structs too. * struct.c (rb_struct_dig): new method Struct#dig. [Feature #11688] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52596 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'struct.c')
-rw-r--r--struct.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/struct.c b/struct.c
index 60ef6d8cfd..d8c781efa6 100644
--- a/struct.c
+++ b/struct.c
@@ -923,6 +923,23 @@ rb_struct_aset(VALUE s, VALUE idx, VALUE val)
return val;
}
+FUNC_MINIMIZED(VALUE rb_struct_lookup(VALUE s, VALUE idx));
+NOINLINE(static VALUE rb_struct_lookup_default(VALUE s, VALUE idx, VALUE notfound));
+
+VALUE
+rb_struct_lookup(VALUE s, VALUE idx)
+{
+ return rb_struct_lookup_default(s, idx, Qnil);
+}
+
+static VALUE
+rb_struct_lookup_default(VALUE s, VALUE idx, VALUE notfound)
+{
+ int i = rb_struct_pos(s, &idx);
+ if (i < 0) return notfound;
+ return RSTRUCT_GET(s, i);
+}
+
static VALUE
struct_entry(VALUE s, long n)
{
@@ -1109,6 +1126,16 @@ rb_struct_size(VALUE s)
return LONG2FIX(RSTRUCT_LEN(s));
}
+static VALUE
+rb_struct_dig(int argc, VALUE *argv, VALUE self)
+{
+ rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
+ self = rb_struct_lookup(self, *argv);
+ if (!--argc) return self;
+ ++argv;
+ return rb_obj_dig(argc, argv, self, Qnil);
+}
+
/*
* A Struct is a convenient way to bundle a number of attributes together,
* using accessor methods, without having to write an explicit class.
@@ -1166,6 +1193,7 @@ InitVM_Struct(void)
rb_define_method(rb_cStruct, "values_at", rb_struct_values_at, -1);
rb_define_method(rb_cStruct, "members", rb_struct_members_m, 0);
+ rb_define_method(rb_cStruct, "dig", rb_struct_dig, -1);
}
#undef rb_intern