diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-11-16 09:21:56 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-11-16 09:21:56 +0000 |
commit | 20690026a7dd7622c7d824de71e337a68a293b63 (patch) | |
tree | c2e21553dc5527199a6caac0588ffb158d9be7dd /struct.c | |
parent | 1ff30ea2b1675fa6bfa50bb5bac1f8cdea8524e1 (diff) |
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.c | 28 |
1 files changed, 28 insertions, 0 deletions
@@ -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 |