Frage

Ich benutze Python schon lange und habe gerade angefangen, mit Ruby herumzuspielen, aber ich finde die Unterschiede zwischen Modulen in den beiden Sprachen wirklich verwirrend, besonders wenn ich durch ihre C-APIs betrachtet habe. Zum Beispiel hier ist ein kleines Ruby C -Modul

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

Wenn ich das so importiere und so nenne

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

Ich erwartete, dass es ähnlich wie Pythons Module funktionieren würde. Ich stelle jedoch fest, dass ich beide verwenden muss PyModule eine Klasse verlängern oder ich muss verwenden include "PyModule". Ich suche nach einer Möglichkeit zu haben PyModule Fügen Sie diese Funktionen dem Modulobjekt ähnlich wie Pythons Semantik bei. Ich bin auch neugierig, was tatsächlich in Ruby passiert, was ihm dieses Verhalten verleiht.

War es hilfreich?

Lösung

Das Modul kann sowohl in Ruby als auch in Python nützlich sein, aber Module in Ruby unterscheiden sich darin, dass sie auch als Mixins dienen.

Ihre Verwirrung ist dazwischen Beispiel Methoden (wie diejenigen, die Sie definieren und die bei Einbeziehung eines Moduls importiert werden) und Singleton Methoden (wie diejenigen, die Sie anrufen möchten und die nicht in der Aufnahme importiert werden).

Sie können verwenden rb_define_singleton_method Anstatt von rb_define_method Und Sie werden den gewünschten Effekt bekommen. In diesem Fall hat Ihr Modul jedoch keine Instanzmethoden, sodass es oder die Erweiterung keinen Effekt hat.

Ich persönlich bevorzuge es, die Methoden als Instanzmethoden zu definieren und das Modul zu erweitern mit sich selbst Die Methoden sind also in beiden Arten verfügbar. In C können Sie verwenden rb_extend_object(PyModule, PyModule); das zu tun.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top