From: Christer Sandberg Date: 2006-09-21T19:00:16+09:00 Subject: Re: Creating a reference to a ruby variable in a C extension David Balmain wrote: > On 9/21/06, Christer Sandberg wrote: >> David Balmain wrote: >> > On 9/21/06, Christer Sandberg wrote: >> >> Vincent Fourmond wrote: >> >> > Hello ! >> >> > >> >> >> Then later on I wan't to use it like this: >> >> >> >> >> >> void call(void) >> >> >> { >> >> >> rb_funcall(ref, rb_intern("some_method"), 0, 0); >> >> >> } >> >> > >> >> > How comes this function has no parameters ? Is it being called >> from >> >> > ruby, or only from C code ? >> >> > >> >> >> >> Thank you for the reply, I'll try to clear things up a bit and explain >> >> what I want to do. >> >> >> >> The function is just an example for the sake of making my question >> a bit >> >> clearer. The real functions I am using has parameters. Those functions >> >> such as the one above will only be called from C code. >> >> >> >> > >> >> > I tend to think that using global variables is not a really good >> >> idea. >> >> > We need a bit more context about what you want to do. Is it a >> class ? >> >> > Will it have several instances ? >> >> > >> >> > In the latter case, have a look at rb_iv_get and rb_iv_set to >> get/set >> >> > instance variables of a class instance, something like >> >> > >> >> > rb_iv_set(self, rb_intern("@variable"), arg); /* in init(...) */ >> >> > >> >> > and >> >> > >> >> > >> >> > >> >> >> rb_funcall(rb_iv_get(self,rb_intern("@variable")),rb_intern("some_method"), >> >> >> >> >> > 0, 0); /* in call */ >> >> > >> >> >> >> Yes, I'm writing a tiny Ruby class in C that wraps and uses a >> bison/flex >> >> generated parser. The saved variable reference will be used for making >> >> calls on the ruby instance. When those calls are made self is long >> gone >> >> out of scope sice it's the parser who triggers the method call. The C >> >> Ruby class just acts as a proxy or adapter between the parser and the >> >> Ruby object. >> > >> > Hi Christer, >> > >> > Instead of saving it as a global variable, you could save it as a >> > class variable. See rb_cvar_[gs]et (defined in variable.c). Just an >> > idea. >> > >> > Cheers, >> > Dave >> > >> >> Hi Dave! >> >> That would work if the passed in object should be shared among all >> instances of my class, but that's not the case since it's a callback >> object that's supplied for a particular instance of my class. >> >> Correct me if I'm wrong but the variable is only global in my C code >> since I haven't made it visible to the Ruby environment with a >> rb_gv_set(const char *name, VALUE value)? >> >> Thanx >> Christer > > Hi Christer, > > Right you are. I can't believe I haven't looked at this method before. > rb_global_variable simply registers the object so that it won't be > garbage collected. Incidentally for those interested, > rb_global_variable is really just an alias for rb_gc_register_address. > If you later want to let the object to be garbage collected you just > need to call rb_gc_unregister_address(&value). I wish I knew about > this a couple of months ago. > > Anyway, now that I know this I think the way you are going about > solving the problem is the correct one. > > Thanks, > Dave > Alright... Didn't know about that method (rb_gc_unregister_address(&value);), thanks Dave! Christer