C-APIのPythonモジュールセマンティクスvs. Rubyモジュールセマンティクス
-
25-10-2019 - |
質問
私は長い間Pythonを使用していて、Rubyをいじり始めたばかりですが、特にC-APIを通して見ると、2つの言語のモジュール間の違いが本当に混乱していることがわかりました。たとえば、ここに小さなルビー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のモジュールはミックスとしても機能するという点で異なります。
あなたの混乱は間にあります 実例 方法(あなたが定義しているものと同様に、モジュールを含めるときにインポートされる)および シングルトン 方法(あなたが電話しようとしているものと同様に、包含時にインポートされていない)。
使用できます rb_define_singleton_method
それ以外の rb_define_method
そして、あなたはあなたが望む効果を得るでしょう。ただし、その場合、モジュールにはインスタンスメソッドがないため、それを含めるか、拡張することは効果がありません。
私は個人的にメソッドをインスタンスメソッドとして定義し、モジュールを拡張することを好みます それ自体が そのため、メソッドは両方の方法で利用できます。 Cでは、使用できます rb_extend_object(PyModule, PyModule);
それをするために。