Семантика модуля Python против Ruby Module Semantics в их APIS

StackOverflow https://stackoverflow.com/questions/9301662

  •  25-10-2019
  •  | 
  •  

Вопрос

Я долгое время использовал Python, и я только начал играть с Ruby, но я нахожу различия между модулями на двух языках, которые действительно запутывают, особенно если смотреть через их C-API. Например, вот небольшой модуль Ruby 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); сделать это.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top