[Ruby] Re: [Ruby] определения переменной в C

Eugene Scripnik Eugene.Scripnik at itgrp.net
Tue Nov 5 13:14:41 MSK 2002


Tuesday, November 5, 2002, 11:40:54 AM, you wrote:

KA> Hi 2 all!
KA> Пишу модуль для Ruby на Си и никак не могу побороть одну вещь.Мне нужно 
KA> создать класс,который изначально не имеет методов и переменных.Когда 
KA> создается класс ruby в Cи, то обычно юзаются ф-ции: Data_Make_Struct и 
KA> Data_Wrap_Struct, но им нужно передавать какой-то тип:
KA> obj = Data_Make_Struct(klass, struct st,0, free_p, p); // вместо struct 
KA> st можно поставить и char или еще че-нить.Но мне нужно создать класс без 
KA> всякой внутренних данных, т.е. без 'struct st' и че-нить подобного.
KA> Плюс ко всему у меня этот класс бужет иметь всего один экземпляр.Мне 
KA> Александр Боковой предлагал определить сразу переменную и доопределять 
KA> методы:

KA> static VALUE fc_video(obj)
KA> {
KA>     return rb_iv_get(obj,"video");
KA> }

KA> void Init_freecraft(void)
KA> {
KA> VALUE vFreeCraft = rb_newobj();
KA> VALUE vVideo = rb_newobj();
KA> OBJSETUP(vFreeCraft,rb_cClass,0); // или OBJSETUP(vFreeCraft,rb_cObject, 
KA> T_CLASS);
KA> OBJSETUP(vVideo,rb_cClass,0); // или flag = T_CLASS
KA> rb_define_variable("$FreeCraft", &vFreeCraft);
KA> rb_iv_set(vFreeCraft,"video",vVideo);
KA> rb_define_method(vFreeCraft, "video", fc_video, 0); // тут-то мы падает
KA> в корку
KA> }

KA> падение происходит на ф-ии st_insert() в rb_add_method(),вызываемый из 
KA> rb_define_method() из-за того,что RCLASS(vFreeCraft)->m_tbl равен нулю.

KA> Как это можно ещё сделать?
Насколько я понимаю, ты пытаешься добавить метод video для обьекта
$FreeCraft. Но есть одна деталь, rb_define_method добавляет
instance_method, то есть метод для экземпляра класса (то что получится
после SomeClass.new). А $FreeCraft не является классом - это готовый
объект. С API для добавления метода к объекту я не знаю. Вместо этого
предлагаю немного иной вариант реализации. Вначале создаем некий класс
не доступный глобально, потом добавляем в него метод, а потом создаем
экземпляр этого класса:

void Init_freecraft(void) {
  // создаем класс
  VALUE cFreeCraft = rb_define_class("FreeCraftClass", rb_cObject);
  // либо VALUE cFreeCraft = rb_class_new(rb_cObject);
  // приклеиваем к нему новый метод
  rb_define_method(cFreeCraft, "video", fc_video, 0);
  // создаем экземпляр класса
  VALUE vFreeCraft = rb_class_new_instance(0, 0, cFreeCraft);
  // создаем глобальную переменную
  rb_define_variable("$FreeCraft", &vFreeCraft);
  rb_iv_set(vFreeCraft,"video",vVideo);
}
Код не тестировался.

-- 
Best regards,
 Eugene [team Enticla] [IT Group]    mailto:Eugene.Scripnik at itgrp.net




More information about the Ruby mailing list