From: Park Heesob Date: 2003-11-28T22:11:45+09:00 Subject: Re: rb_hash_aref question: symbols vs strings Hi, > > Hi all, > > I'm writing an extension, and I'm having a little trouble with using a > hash for keyword arguments. I want to allow a API like this: > > Foo.test( > :bar => "hello", > 'baz' => "world" > ) > > In the extension to get the key value I do this: > > VALUE rbBar = rb_hash_aref(myHash,rb_str_new2("bar")); > > If the key "bar" is a string, that works fine. However, that returns > nil (not a symbol) if "bar" is a symbol. I know I can do rb_iterate > and I can detect if hash keys are symbols, but I don't know how to > permanately change the key back to a string, i.e. it appears to pass a > copy of the hash, rather than a reference. > > // Iterate over hash. Assume that rb_sym2str() works properly. > static VALUE parse_hash(VALUE array, VALUE class) > { > VALUE key, tkey, val; > > key = rb_ary_entry(array, 0); // Get key > val = rb_ary_entry(array, 1); // Get value > > if(TYPE(key) == T_SYMBOL){ > key = rb_sym2str(key); // Convert T_SYMBOL to T_STRING > printf("Key is now: %s\n",STR2CSTR(key)); // Verify string > rb_ary_store(array,0,key); // Doesn't work > } > > return array; > } > > Any ideas? > > Regards, > > Dan > > Here is my solution: hash = Foo.test( :bar => "hello", 'baz' => "world" ) static VALUE test(VALUE klass,VALUE myHash) { int i; VALUE ary = rb_funcall(myHash,rb_intern("keys"),0); for(i=0;ilen;i++) { if(TYPE(RARRAY(ary)->ptr[i])==T_STRING) printf("key = %s, val = %s\n", STR2CSTR(RARRAY(ary)->ptr[i]), STR2CSTR(rb_hash_aref(myHash,RARRAY(ary)->ptr[i]))); if(TYPE(RARRAY(ary)->ptr[i])==T_SYMBOL) printf("key = %s, val = %s\n", STR2CSTR(rb_funcall(RARRAY(ary)->ptr[i],rb_intern("inspect"),0)), STR2CSTR(rb_hash_aref(myHash,RARRAY(ary)->ptr[i]))); } rb_hash_aset(myHash, rb_str_new2("baz"), rb_str_new2("aaa")); rb_hash_aset(myHash, rb_eval_string(":bar"), rb_str_new2("bbb")); for(i=0;ilen;i++) { if(TYPE(RARRAY(ary)->ptr[i])==T_STRING) printf("key = %s, val = %s\n", STR2CSTR(RARRAY(ary)->ptr[i]), STR2CSTR(rb_hash_aref(myHash,RARRAY(ary)->ptr[i]))); if(TYPE(RARRAY(ary)->ptr[i])==T_SYMBOL) printf("key = %s, val = %s\n", STR2CSTR(rb_funcall(RARRAY(ary)->ptr[i],rb_intern("inspect"),0)), STR2CSTR(rb_hash_aref(myHash,RARRAY(ary)->ptr[i]))); } return myHash; } Regards, Park Heesob