[Ruby] Re: [Ruby] определения переменной в C
Alexander Bokovoy
a.bokovoy at sam-solutions.net
Tue Nov 5 14:12:13 MSK 2002
On Tue, Nov 05, 2002 at 12:14:41PM +0200, Eugene Scripnik wrote:
> 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);
> }
> Код не тестировался.
Это слишком много. Достаточно определять методы как singleton_method:
#define _GNU_SOURCE
#include "ruby.h"
#include "intern.h"
#include "node.h"
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
extern VALUE rb_progname;
static VALUE my_method(VALUE self) {
rb_warn("my_method called!");
return Qtrue;
}
int main(int argc, char *argv[]) {
VALUE foo;
ruby_init();
ruby_script(argv[0]);
rb_argv0 = rb_progname;
/* Do not pass progname as argument */
ruby_set_argv(argc-1, &argv[1]);
ruby_sourcefile = rb_source_filename(argv[0]);
ruby_init_loadpath();
/* --------- Это и есть то, что нужно? --------------- */
foo = rb_newobj();
OBJSETUP(foo, rb_cObject, T_CLASS);
rb_define_singleton_method(foo, "my_method", my_method, 0);
/* --------------------------------------------------- */
rb_define_variable("$foo", &foo);
rb_compile_string(argv[0],rb_str_new2("puts $foo.my_method"), 1);
ruby_run();
return 0;
}
Код работает, компилировать с помощью:
#!/usr/bin/env ruby
require 'rbconfig.rb'
include Config
`#{CONFIG['CC']} #{CONFIG['CFLAGS']} -I#{CONFIG['archdir']} #{CONFIG['LIBRUBYARG']} #{CONFIG['LIBS']} -o foo foo.c`
--
/ Alexander Bokovoy
---
quark:
The sound made by a well bred duck.
More information about the Ruby
mailing list