Saturday, January 15, 2011

Writing Ruby Extensions in C - Part 9, Arrays

This is the ninth in my series of posts about writing ruby extensions in C. The first post talked about the basic structure of a project, including how to set up building. The second post talked about generating documentation. The third post talked about initializing the module and setting up classes. The fourth post talked about types and return values. The fifth post focused on creating and handling exceptions. The sixth post talked about ruby catch and throw blocks. The seventh post talked about dealing with numbers. The eighth post talked about strings. This post will focus on arrays.

Arrays


The nice thing about arrays in ruby C extensions is that they act very much like the ruby arrays they represent. There are a few functions to know about:
  • rb_ary_new() - create a new array with 0 elements. Elements can be added later using rb_ary_push(), rb_ary_store(), or rb_ary_unshift().
  • rb_ary_new2(size) - create a new array with size elements
  • rb_ary_store(array, index, value) - put the ruby value into array at index. This can be used to create sparse arrays; intervening elements that have not yet had values assigned will be set to nil
  • rb_ary_push(array, value) - put value at the end of the array
  • rb_ary_unshift(array, value) - put value at the start of the array
  • rb_ary_pop(array) - pop the last element of array off and return it
  • rb_ary_shift(array) - remove the first element of array and return it
  • rb_ary_entry(array, index) - examine array element located at index without changing array
  • rb_ary_dup(array) - copy array and return the copy
  • rb_ary_to_s(array) - invoke the "to_s" method on the array. Note that this concatenates the array elements together without spacing, so is not generally useful
  • rb_ary_join(array, string_object) - create a string by converting each element of the array to a string separated by string_object. If string_object is Qnil, then no separator is used
  • rb_ary_reverse(array) - reverse the order of all of the elements in array
  • rb_ary_to_ary(ruby_object) - create an array out of any ruby object. If the object is already an array, a reference to the same object is returned. If the object supports the "to_ary" method, then "to_ary" is invoked on the object and the result is returned. If neither of the previous are true, then a new array with 1 element containing the object is returned

An example should make most of this clear:

 1) VALUE result, elem, arr2, mystr;
 2)
 3) result = rb_ary_new();
 4) // result is now []
 5) rb_ary_push(result, INT2FIX(1));
 6) // result is now [1]
 7) rb_ary_push(result, INT2FIX(2));
 8) // result is now [1, 2]
 9) rb_ary_unshift(result, INT2FIX(0));
10) // result is now [0, 1, 2]
11) rb_ary_store(result, 3, INT2FIX(3));
12) // result is now [0, 1, 2, 3]
13) rb_ary_store(result, 5, INT2FIX(5));
14) // result is now [0, 1, 2, 3, nil, 5]
15) elem = rb_ary_pop(result);
16) // result is now [0, 1, 2, 3, nil] and elem is 5
17) elem = rb_ary_shift(result);
18) // result is now [1, 2, 3, nil] and elem is 0
19) elem = rb_ary_entry(result, 0);
20) // result is now [1, 2, 3, nil] and elem is 1
21) arr2 = rb_ary_dup(result);
22) // result is now [1, 2, 3, nil] and arr2 is [1, 2, 3, nil]
23) mystr = rb_ary_to_s(result);
24) // result is now [1, 2, 3, nil] and mystr is 123
25) mystr = rb_ary_join(result, rb_str_new2("-"));
26) // result is now [1, 2, 3, nil] and mystr is 1-2-3-
27) rb_ary_reverse(result);
28) // result is now [nil, 3, 2, 1]
29) rb_ary_shift(result);
30) // result is now [3, 2, 1]
31) result = rb_ary_to_ary(rb_str_new2("hello"));
32) // result is now ["hello"]

1 comment:

  1. This blog awesome and i learn a lot about programming from here.The best thing about this blog is that you doing from beginning to experts level.

    Love from

    ReplyDelete