From: Yukihiro Matsumoto Date: 2008-01-08T09:34:48+09:00 Subject: Re: Using "sort!" in a C extension (1.9 problem) Hi, Sorry for being late to reply. I have missed your mail. In message "Re: Using "sort!" in a C extension (1.9 problem)" on Sun, 30 Dec 2007 02:49:47 +0900, Andre Nathan writes: |In ruby 1.8, I could use Array#sort! in a C extension like this: | |static VALUE |call_sort_bang(VALUE ary) |{ | return rb_funcall(ary, rb_intern("sort!"), 0); |} | |static VALUE |sort_i(VALUE ary) |{ | long v1 = FIX2LONG(RARRAY_PTR(ary)[0]); | long v2 = FIX2LONG(RARRAY_PTR(ary)[1]); | return LONG2FIX(v1 - v2); |} | |static VALUE |foo(void) |{ | VALUE ary = rb_ary_new(); | rb_ary_push(ary, INT2FIX(1)); | rb_ary_push(ary, INT2FIX(0)); | rb_ary_push(ary, INT2FIX(2)); | rb_iterate(call_sort_bang, ary, sort_i, 0); | rb_funcall(rb_mKernel, rb_intern("p"), 1, ary); | return a; |} | |This would print "[0, 1, 2]" as expected. However, it doesn't work in |ruby1.9 compiled from svn (checked out today). The problem seems to be |that only one of the array elements is being passed to sort_i(), instead |of a pair of elements as it's done in 1.8. | |What is the correct way to do this in 1.9? In general, if you want to get multiple values from yield, you have to use arguments added in 1.9: static VALUE sort_i(VALUE a1, VALUE a2, int argc, VALUE *argv) { long v1 = FIX2LONG(RARRAY_PTR(argv[0])); long v2 = FIX2LONG(RARRAY_PTR(argv[1])); return LONG2FIX(v1 - v2); } You may need to check argc if they are variable. matz.