[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