我正在研究Programming Ruby 1.9的示例。是否有可能创建不暴露给Ruby的实例变量,仅在C中可见 - 例如初始化t_init中的C结构并在t_add中使用它?如何在C扩展中的Ruby层隐藏实例变量?
如果我在id_push下面声明结构或变量,它是类结构/变量,我需要实例。
是否有可能在不使用Data_Wrap_Struct/Data_Get_Struct或rb_iv_set/rb_iv_get的情况下实现,因为Ruby中不需要实例变量,仅从C中仅可见?
#include "ruby.h"
static ID id_push;
// how to define instance variables here?
static VALUE t_init(VALUE self) {
VALUE arr;
arr = rb_ary_new();
rb_iv_set(self, "@arr", arr);
return self;
}
static VALUE t_add(VALUE self, VALUE obj) {
VALUE arr;
arr = rb_iv_get(self, "@arr");
rb_funcall(arr, id_push, 1, obj);
return arr;
}
VALUE cTest;
void Init_my_test() {
cTest = rb_define_class("MyTest", rb_cObject);
rb_define_method(cTest, "initialize", t_init, 0);
rb_define_method(cTest, "add", t_add, 1); id_push = rb_intern("push");
}
这太可怕了:-)它可能会工作,但你确定GC会用这些部分可访问的东西做正确的事情吗?任何备受推崇的扩展库实际上是否使用此技术作为快捷方式(以隐藏由C添加的实例变量)? –
好的,发现'rb_iv_set'和'rb_ivar_set'之间的区别,现在有意义(和+1),最初我以为你建议在没有'@'的情况下使用'rb_iv_set'。 。 。 –
它的工作原理是,我现在可以将C结构保存为类实例变量,仅在C中可见,并且在shell尝试显示它们并且conf.echo处于活动状态时,irb中不会出现段错误。 Ruby垃圾收集器也会清理这些变量,或者? – bsrdjan