Я хотел бы знать, как добавить собственный метод, написанный на расширении C, до уже существующего класса Ruby? Я только нашел функцию, которая позволяет вам создать новый класс Ruby, но ни один из них не возвращает уже существующий класс.Добавить встроенный метод C в ранее существовавший класс Ruby
ответ
Да, вы можете. В любом случае вы используете rb_define_method
(или rb_define_singleton_method
для однотоновых методов). Если у вас есть функция переменного тока называется rb_some_function
, что ожидает 1 параметр (в дополнении к параметру самого) вы могли бы сделать
rb_define_method(someClass,
"some_function",
RUBY_METHOD_FUNC(rb_some_function),
1);
Это до вас SomeClass, является ли только что созданным классом (созданный с rb_define_class_under
или rb_define_class
) или существующий класс. Вы можете использовать метод rb_const_get
(тот же, что и объект const_get
), чтобы получить существующие классы.
someClass = rb_const_get(rb_cObject, rb_intern("SomeClass"));
rb_define_class
также принести существующий класс для вас (по аналогии с открытия класса в рубин). Он будет взорваться аналогичным образом, если вы попытаетесь определить класс с суперклассом, а класс уже существует с другим.
Как сказал Нейл, rb_define_class повторно открывает существующий класс или лучше использовать rb_const_get? – yageek
'rb_const_get (rb_cObject, rb_intern (" Foo "));' аналогично помещению символа-символа 'Foo' в ваш код. Например. если вы, в Ruby, напишите 'def Foo.bar' напрямую (по какой-либо причине). В то время как 'rb_define_class (" Foo ", rb_cObject)' такой же, как и запись в Ruby 'class Foo'. Я бы использовал их соответственно, что означает, что я вообще избегал подхода 'rb_const_get', если бы я не писал расширение, которое выполняло мета-программирование класса. –
Если я ожидаю, что класс существует, я бы использовал rb_const_get - если класс нет, тогда я бы хотел, чтобы мой код взорвался, а не просто создавал новый класс. Зависит от того, насколько параноик я чувствую, хотя –
Простым подходом imho было бы определить класс ruby с c-расширением, а затем снова открыть его в чистом рубине. Правильно? В Ruby вы не можете переопределить класс, просто откройте его и добавьте в него. – nathanvda
У меня не было проблем с этим. AFAIK, связанные с C функциями - например, 'rb_define_class' будет довольно счастливо действовать, чтобы« повторно открыть »классы и модули, потому что они фактически являются теми же функциями, что и в MRI Ruby. –