Domanda

Sto usando Python per molto tempo e ho appena iniziato a giocare intorno con Ruby, ma mi sto trovando le differenze tra moduli in due lingue molto confusa, soprattutto se visti attraverso i loro C-API. Ad esempio, ecco un piccolo modulo rubino C

#include "Python.h"
#include "ruby.h"

VALUE PyModule = Qnil;
void Init_pymodule();
VALUE method_Py_Initialize();
VALUE method_PyRun_SimpleString();

void Init_pymodule() {
    PyModule = rb_define_module("PyModule");
    rb_define_method(PyModule, "Py_Initialize", method_Py_Initialize, 0);
    rb_define_method(PyModule, "PyRun_SimpleString", method_PyRun_SimpleString, 1);
}

VALUE method_Py_Initialize(VALUE self) {
    Py_Initialize();
    return Qnil;
}

VALUE method_PyRun_SimpleString(VALUE self, VALUE command) {
    return INT2NUM(PyRun_SimpleString(RSTRING(command)->as.ary));
}

Quando importo e chiamata che in questo modo

require "pymodule"
PyModule.Py_Initialize()
PyModule.PyRun_SimpleString("print 'hellooo'")

mi aspettavo di lavorare simile a come i moduli di Python avrebbe funzionato. Tuttavia, mi sto trovando che devo sia per uso PyModule per estendere una classe o devo usare include "PyModule". Sto cercando un modo per avere PyModule allegare queste funzioni per l'oggetto modulo simile alla semantica di Python. Sono anche curioso di ciò che sta realmente accadendo in Ruby che gli conferisce questo comportamento.

È stato utile?

Soluzione

Il modulo può essere utile come namespace, sia Ruby e Python, ma moduli in rubino sono differenti in quanto servono come mixins troppo.

La vostra confusione è tra istanza metodi (come quelli che si sta definendo e che vengono importati quando si include un modulo) e Singleton metodi (come quelli che si sta tentando di chiamano e che non vengono importate in materia di inclusione).

È possibile utilizzare rb_define_singleton_method invece di rb_define_method e si otterrà l'effetto desiderato. In tal caso, però, il modulo non avrà alcun metodi di istanza, quindi compresi o di un'estensione non avrà alcun effetto.

Io personalmente preferisco definire i metodi come metodi di istanza ed estendere il modulo con se stesso in modo che i metodi sono disponibili in entrambi i modi. In C, è possibile utilizzare rb_extend_object(PyModule, PyModule); di farlo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top