From: David Balmain Date: 2006-09-21T18:45:08+09:00 Subject: Re: Creating a reference to a ruby variable in a C extension 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