[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

How to do Hash#each_pair from C extension?

Bill Kelly

12/29/2006 8:23:00 AM

Hi,

I'm trying to copy all the key/value pairs from a Ruby
hash into an STL hash. (BTW, I'm using Ruby 1.8.4 and
cannot change the ruby version easily.)

It looks like rb_hash_foreach() in hash.c does exactly
what I want--allows me to pass in a function pointer,
which it will invoke yielding each key/value pair--but
it's declared static in hash.c.

I looked at duplicating that functionality in my own
C code, but it requires "st.h" as well as constants
such as HASH_DELETED which are defined privately in
hash.c.

Is there a different way I should be going about this?


Thanks for any help,

Bill



3 Answers

Ross Bamford

12/29/2006 12:57:00 PM

0

On Fri, 29 Dec 2006 08:22:34 -0000, Bill Kelly <billk@cts.com> wrote:

> Hi,
>
> I'm trying to copy all the key/value pairs from a Ruby
> hash into an STL hash. (BTW, I'm using Ruby 1.8.4 and
> cannot change the ruby version easily.)
>
> It looks like rb_hash_foreach() in hash.c does exactly
> what I want--allows me to pass in a function pointer,
> which it will invoke yielding each key/value pair--but
> it's declared static in hash.c.
>
> I looked at duplicating that functionality in my own
> C code, but it requires "st.h" as well as constants
> such as HASH_DELETED which are defined privately in
> hash.c.
>
> Is there a different way I should be going about this?
>

Maybe try something like:

static VALUE hsh_iterfunc(VALUE data_ary, VALUE hsh) {
VALUE key =3D rb_ary_entry(data_ary, 0);
VALUE value =3D rb_ary_entry(data_ary, 1);

// do whatever, e.g.
rb_funcall(rb_mKernel, rb_intern("puts"), 2, key, value);

return data_ary;
}


VALUE ruby_iterhsh(VALUE self, VALUE hsh) {
return rb_iterate(rb_each, hsh, hsh_iterfunc, hsh);
}

// ... later,

rb_define_method(cSomeClass, "iterhsh", ruby_iterhsh, 1);



Hope that helps,
Ross

-- =

Ross Bamford - rosco@roscopeco.remove.co.uk

Bill Kelly

1/3/2007 5:05:00 AM

0

From: "Ross Bamford" <rosco@roscopeco.remove.co.uk>
> On Fri, 29 Dec 2006 08:22:34 -0000, Bill Kelly <billk@cts.com> wrote:
>
> > I'm trying to copy all the key/value pairs from a Ruby
> > hash into an STL hash. (BTW, I'm using Ruby 1.8.4 and
> > cannot change the ruby version easily.)
>
> Maybe try something like:
>
> static VALUE hsh_iterfunc(VALUE data_ary, VALUE hsh) {
> VALUE key = rb_ary_entry(data_ary, 0);
> VALUE value = rb_ary_entry(data_ary, 1);
>
> // do whatever, e.g.
> rb_funcall(rb_mKernel, rb_intern("puts"), 2, key, value);
>
> return data_ary;
> }
>
>
> VALUE ruby_iterhsh(VALUE self, VALUE hsh) {
> return rb_iterate(rb_each, hsh, hsh_iterfunc, hsh);
> }

Thanks! Works great.

What I'm passing in as the second parameter isn't really a VALUE,
it's a pointer to the STL hash. As far as I could tell from grepping
the ruby sources, that *seems* to be legal (some ruby code passes
a NODE* for the second parameter, masquerading as a VALUE.)

(Unless a NODE* really is a VALUE, in which case my passing in
a fake VALUE maybe isn't so good after all. I'm a little uncomfortable
not knowing for sure...)


Regards,

Bill


Ross Bamford

1/3/2007 9:31:00 AM

0

On Wed, 03 Jan 2007 05:05:21 -0000, Bill Kelly <billk@cts.com> wrote:

> From: "Ross Bamford" <rosco@roscopeco.remove.co.uk>
>> On Fri, 29 Dec 2006 08:22:34 -0000, Bill Kelly <billk@cts.com> wrote:=

>> > I'm trying to copy all the key/value pairs from a Ruby
>> > hash into an STL hash. (BTW, I'm using Ruby 1.8.4 and
>> > cannot change the ruby version easily.)
>>
>> Maybe try something like:
>> static VALUE hsh_iterfunc(VALUE data_ary, VALUE hsh) {
>> VALUE key =3D rb_ary_entry(data_ary, 0);
>> VALUE value =3D rb_ary_entry(data_ary, 1);
>> // do whatever, e.g.
>> rb_funcall(rb_mKernel, rb_intern("puts"), 2, key, value);
>> return data_ary;
>> }
>> VALUE ruby_iterhsh(VALUE self, VALUE hsh) {
>> return rb_iterate(rb_each, hsh, hsh_iterfunc, hsh);
>> }
>
> Thanks! Works great.
>

No problem :)

> What I'm passing in as the second parameter isn't really a VALUE,
> it's a pointer to the STL hash. As far as I could tell from grepping
> the ruby sources, that *seems* to be legal (some ruby code passes
> a NODE* for the second parameter, masquerading as a VALUE.)
>
> (Unless a NODE* really is a VALUE, in which case my passing in
> a fake VALUE maybe isn't so good after all. I'm a little uncomfortabl=
e
> not knowing for sure...)
>

No, that should be fine - ruby guarantees that VALUE casts to void*, and=
=

the second argument is purely for your use.

Cheers,
-- =

Ross Bamford - rosco@roscopeco.remove.co.uk