Python模块语义与Ruby模块语义在其C-apis中
-
25-10-2019 - |
题
我已经使用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);
要做到这一点。
不隶属于 StackOverflow