How to get keys from hash - ruby c extension
Asked Answered
B

2

7

I am looking for a function which can get me all the keys from hash or I can loop through the hash to retrieve single key at a time.

Currently I am hardcoding key

VALUE option = rb_hash_aref(options, rb_str_new2("some_key"));
Brittaniebrittany answered 10/12, 2014 at 16:15 Comment(0)
A
2

You can iterate over the key/value pairs with a callback function using rb_hash_foreach (blog post w/an example):

void rb_hash_foreach(VALUE, int (*)(ANYARGS), VALUE);

There is an rb_hash_keys in MRI, but it's not in any header files it seems, so using it may be risky.

Allanallana answered 10/12, 2014 at 17:45 Comment(8)
Yup rb_hash_keys complains use of undeclared identifier 'rb_hash_keys'Brittaniebrittany
Do you have any working example? I am getting this error candidate function not viable: no known conversion from 'int (VALUE, VALUE, VALUE)' to 'int (*)(...)' for 2nd argument void rb_hash_foreach(VALUE, int (*)(ANYARGS), VALUE);Brittaniebrittany
The MRI source has an example in rb_hash_keys: rxr.whitequark.org/mri/source/hash.c#1627Allanallana
error: use of undeclared identifier 'rb_hash_keys';Brittaniebrittany
Well yeah, that function contains the example.Allanallana
I followed MRI source example but eventually I got the same error candidate function not viable: no known conversion from 'int (VALUE, VALUE, VALUE)' to 'int (*)(...)' for 2nd argument void rb_hash_foreach(VALUE, int (*)(ANYARGS), VALUE);This is the code I am trying ` VALUE ary; ary = rb_ary_new(); rb_hash_foreach(opts, convert_keys_to_a, ary);` static int convert_keys_to_a(VALUE key, VALUE value, VALUE ary) { if (logic) return ST_CONTINUE; if (logic { rb_hash_foreach(value, convert_keys_to_a, ary); } return rb_ary_push(ary, key); }Brittaniebrittany
What ruby version? Compiler? Compiler flags? How are you building this? Empty functions with these names compiles fine for me using these basic instructions.Allanallana
If you are compiling for Rubinius, you may need to include the hash libraries yourself (they are not automatically included with ruby.h): // Force inclusion of hash declarations (only MRI includes by default) #ifdef HAVE_RUBY_ST_H #include "ruby/st.h" #else #include "st.h" #endifWirth
B
1

You could always make a call to the Ruby method itself:

VALUE keys = rb_funcall(hash, rb_intern("keys"), 0)
Brittne answered 12/1, 2015 at 11:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.