我正在研究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