Module sémantique python par rapport à la sémantique du module Ruby dans leurs C-API
-
25-10-2019 - |
Question
J'utilise Python depuis longtemps et je viens juste de commencer à jouet autour avec Ruby, mais je trouve les différences entre les modules dans les deux langues vraiment déroutant, surtout vu à travers leurs C-API. Par exemple, voici un petit module rubis 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));
}
Quand je l'importation et l'appel qui, comme si
require "pymodule"
PyModule.Py_Initialize()
PyModule.PyRun_SimpleString("print 'hellooo'")
Je m'y attendais à travailler semblable à la façon des modules de python travailleraient. Cependant, je me rends compte que je dois soit utiliser PyModule
pour étendre une classe ou je dois utiliser include "PyModule"
. Je suis à la recherche d'un moyen d'avoir PyModule
attacher ces fonctions à l'objet module similaire à la sémantique de Python. Je suis aussi curieux de savoir ce qui se passe réellement dans Ruby qui lui donne ce comportement.
La solution
Module peut être utile que les espaces de noms, dans les deux Ruby et Python, mais modules Ruby sont différents en ce sens qu'ils servent mixins aussi.
Votre confusion est entre par exemple méthodes (comme celles que vous définissez et qui sont importés en incluant un module) et singleton méthodes (comme ceux que vous essayez de appel et qui ne sont pas importées sur l'inclusion).
Vous pouvez utiliser rb_define_singleton_method
au lieu de rb_define_method
et vous obtiendrez l'effet que vous voulez. Dans ce cas, cependant, votre module aura pas des méthodes d'instance, donc y compris ou son extension n'aura aucun effet.
Personnellement, je préfère définir les méthodes telles que les méthodes d'instance et d'étendre le module avec lui-même de sorte que les méthodes sont disponibles dans les deux sens. En C, vous pouvez utiliser rb_extend_object(PyModule, PyModule);
pour le faire.