我已经使用Python很长一段时间了,我刚刚开始与Ruby一起玩耍,但是我发现两种语言中模块之间的差异确实令人困惑,尤其是当通过其C-apis查看时。例如,这是一个小红宝石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中实际发生的事情,从而赋予了这种行为。

有帮助吗?

解决方案

在Ruby和Python中,模块可以用作名称空间,但是Ruby中的模块也不同,因为它们也用作Mixins。

你的困惑介于 实例 方法(例如您定义的方法,包括模块包括在内的方法)和 辛格尔顿 方法(例如您试图调用的方法,而不是在包含中导入的方法)。

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

我个人更喜欢将方法定义为实例方法并扩展模块 与自己 因此,这些方法都可以通过两种方式可用。在C中,您可以使用 rb_extend_object(PyModule, PyModule); 要做到这一点。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top