0

我已经使用 Python 很长时间了,而且我刚刚开始玩弄 Ruby,但是我发现这两种语言中模块之间的差异确实令人困惑,尤其是通过它们的 C-API 来查看时。例如,这里是一个小的 ruby​​ 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));
}

当我像这样导入并调用它时

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

我希望它的工作方式类似于 python 模块的工作方式。但是,我发现我必须使用PyModule来扩展一个类,或者我必须使用include "PyModule". 我正在寻找一种PyModule将这些函数附加到类似于 Python 语义的模块对象的方法。我也很好奇 Ruby 中实际发生的事情导致了这种行为。

4

1 回答 1

3

模块在 Ruby 和 Python 中都可以用作命名空间,但 Ruby 中的模块的不同之处在于它们也用作混合。

您的困惑在于实例方法(例如您正在定义并且在包含模块时导入的那些)和单例方法(例如您尝试调用并且在包含时未导入的那些)。

你可以使用rb_define_singleton_method代替,rb_define_method你会得到你想要的效果。但是,在这种情况下,您的模块将没有任何实例方法,因此包含它或扩展它不会有任何效果。

我个人更喜欢将方法定义为实例方法,并使用自身扩展模块,因此这些方法可以两种方式使用。在 C 中,您可以使用它rb_extend_object(PyModule, PyModule);来执行此操作。

于 2012-02-15T22:31:49.543 回答