diff options
author | Kazuki Tsujimoto <kazuki@callcc.net> | 2019-11-08 11:37:07 +0900 |
---|---|---|
committer | Kazuki Tsujimoto <kazuki@callcc.net> | 2019-11-08 11:37:46 +0900 |
commit | d4da74ea786da7906fdb85e593593a9c6c11fe96 (patch) | |
tree | 98682735d82abf9c8d05bc5c718c00ee88d17248 /struct.c | |
parent | 766115010932d977142097f60c76dd20af73196e (diff) |
Define Struct#deconstruct_keys
Diffstat (limited to 'struct.c')
-rw-r--r-- | struct.c | 28 |
1 files changed, 28 insertions, 0 deletions
@@ -944,6 +944,33 @@ rb_struct_to_h(VALUE s) return h; } +static VALUE +rb_struct_deconstruct_keys(VALUE s, VALUE keys) +{ + VALUE h; + long i; + + if (NIL_P(keys)) { + return rb_struct_to_h(s); + } + if (UNLIKELY(!RB_TYPE_P(keys, T_ARRAY))) { + rb_raise(rb_eTypeError, + "wrong argument type %"PRIsVALUE" (expected Array or nil)", + rb_obj_class(keys)); + + } + h = rb_hash_new_with_size(RARRAY_LEN(keys)); + for (i=0; i<RARRAY_LEN(keys); i++) { + VALUE key = RARRAY_AREF(keys, i); + int i = rb_struct_pos(s, &key); + if (i < 0) { + return rb_hash_new_with_size(0); + } + rb_hash_aset(h, key, RSTRUCT_GET(s, i)); + } + return h; +} + /* :nodoc: */ VALUE rb_struct_init_copy(VALUE copy, VALUE s) @@ -1357,6 +1384,7 @@ InitVM_Struct(void) rb_define_method(rb_cStruct, "dig", rb_struct_dig, -1); rb_define_method(rb_cStruct, "deconstruct", rb_struct_to_a, 0); + rb_define_method(rb_cStruct, "deconstruct_keys", rb_struct_deconstruct_keys, 1); } #undef rb_intern |