Park Heesob
11/28/2003 1:12:00 PM
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;i<RARRAY(ary)->len;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;i<RARRAY(ary)->len;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