2012-02-15 4 views
0

Я долгое время использовал Python, и я только начал играть с Ruby, но я обнаружил различия между модулями в двух языки действительно запутывают, особенно при просмотре через их C-API. Например, вот небольшой модуль рубин CСемантика модуля модуля Python и семантика модуля Ruby в их C-API

#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)); 
} 

Когда я импортировать и называть это как так

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

Я ожидал, что он работает аналогично тому, как модули Python, будет работать. Тем не менее, я считаю, что мне нужно либо использовать PyModule для расширения класса, либо я должен использовать include "PyModule". Я ищу способ, чтобы PyModule присоединял эти функции к объекту модуля, подобному семантике Python. Мне также интересно, что на самом деле происходит в Ruby, что дает ему такое поведение.

ответ

3

Модуль может быть полезен как пространства имен, как в Ruby, так и в Python, но модули в Ruby отличаются тем, что они также служат в качестве миксинов.

Ваша путаница между экземпляра методы (как те, которые вы определяете и импортируются при включении модуля) и одноплодной методы (например, те, которые вы пытаетесь вызвать, и что не ввозятся на включение) ,

Вы можете использовать rb_define_singleton_method вместо rb_define_method, и вы получите эффект, который вы хотите. В этом случае, однако, ваш модуль не будет иметь каких-либо методов экземпляра, поэтому включение его или расширение его не будет иметь никакого эффекта.

Я лично предпочитаю определять методы как методы экземпляра и распространять модуль с собой, поэтому методы доступны в обоих направлениях. В C вы можете использовать rb_extend_object(PyModule, PyModule); для этого.

+0

Да, это точно проблема. Ruby имеет интересную модель метакласса, учитывая, что вы можете расширить класс с собой. – dcolish

Смежные вопросы