Hashes
The nice thing about hashes in ruby C extensions is that they act very much like the ruby hashes they represent. There are a few functions to know about:
- rb_hash_new() - create a new ruby Hash
- rb_hash_aset(hash, key, value) - set the hash key to value
- rb_hash_aref(hash, key) - get the value for hash key
- rb_hash_foreach(hash, callback, args) - call callback for each key,value pair in the hash. Callback must have a prototype of int (*cb)(VALUE key, VALUE val, VALUE in)
An example will demonstrate this:
1) int do_print(VALUE key, VALUE val, VALUE in) {
2) fprintf(stderr, "Input data is %s\n", StringValueCStr(in));
3)
4) fprintf(stderr, "Key %s=>Value %s\n", StringValueCStr(key),
5) StringValueCStr(val));
6)
7) return ST_CONTINUE;
8) }
9)
10) VALUE result;
11) VALUE val;
12)
13) result = rb_hash_new();
14) // result is now {}
15) rb_hash_aset(result, rb_str_new2("mykey"),
16) rb_str_new2("myvalue"));
17) // result is now {"mykey"=>"myvalue"}
18) rb_hash_aset(result, rb_str_new2("anotherkey"),
19) rb_str_new2("anotherval"));
20) // result is now {"mykey"=>"myvalue",
21) // "anotherkey"=>"anotherval"}
22) rb_hash_aset(result, rb_str_new2("mykey"),
23) rb_str_new2("differentval"));
24) // result is now {"mykey"=>"differentval",
25) // "anotherkey"=>"anotherval"}
26) val = rb_hash_aref(result, rb_str_new2("mykey"));
27) // result is now {"mykey"=>"differentval",
28) // "anotherkey"=>"anotherval"},
29) // val is "differentval"
30) rb_hash_delete(result, rb_str_new2("mykey"));
31) // result is now {"anotherkey"=>"anotherval"}
32)
33) rb_hash_foreach(result, do_print, rb_str_new2("passthrough"));
Most of this is pretty straightforward. The most interesting part of this is line 33, where we perform an operation on all elements in the hash by utilizing a callback. This callback is defined on lines 1 through 8, and takes in the key, value, and the user data provided to the original rb_hash_foreach() call. The return code from the callback defines what happens to the processing of the rest of the hash. If the return value is ST_CONTINUE, then the rest of the hash is processed as normal. If the return value is ST_STOP, then no further processing of the hash is done. If the return value is ST_DELETE, then the current hash key is deleted from the hash and the rest of the hash is processed. If the return value is ST_CHECK, then the hash is checked to see if it has been modified during this operation. If so, processing of the hash stops.
Update: Fixed up the example code to show on the screen.
Hi I am using you example and getting this error
ReplyDeletecandidate function not viable: cannot convert argument of incomplete type 'void' to 'VALUE' (aka 'unsigned long')
VALUE rb_hash_aref(VALUE, VALUE);