Как передать блок, написанный на C, в Ruby rb_mod_refine?

#c #ruby #mri #ruby-native-extensions

#c #ruby #mri #ruby-native-extensions

Вопрос:

Возможно, в более общем плане, как вы передаете блок, написанный на C, другой функции C, которая принимает блок? Я знаю, что могу сделать что-то вроде этого:

 VALUE refine_foobar(VALUE block_arg, VALUE data, int argc, VALUE* argv) {
  // block code here
  return Qnil;
}

void Init_mything() {
  VALUE mod = rb_define_module("Foobar");
  rb_block_call(mod, rb_intern("refine"), 0, NULL, refine_foobar, Qnil);
}
  

но я чувствую, что должен быть способ вызвать rb_mod_refine напрямую, а не проходить через rb_block_call .

Есть идеи? Спасибо!

Комментарии:

1. По иронии судьбы я понял, что rb_mod_refine это не упоминается в ruby. файл заголовка h, так что, возможно, я даже не должен его использовать 🙁

Ответ №1:

В текущем использовании уточнения применяются к модулям. Это прямо там, в названии метода.

AFAIK, он напрямую не работает с блоками.

Единственный способ, которым я могу видеть, что это работает, — создать метод «C» в модуле, а затем использовать код ruby для применения этого модуля в качестве уточнения обычным способом.

Комментарии:

1. Хм, я не уверен, что понимаю. Уточнения определяются внутри модулей, но сами по себе не являются модулями (по крайней мере, не с точки зрения API верхнего уровня). Другими словами, я не знаю, возможно ли «применить этот модуль в качестве уточнения». Однако модуль, определенный на C, может быть включен в переданный блок refine . Я попробую.

2. Уточнения изменяют модуль с областью видимости. Метод include импортирует методы из модуля. Если это сделано в уточнении, то модуль используется для применения изменений к другому модулю в этом уточнении.

3. Да, это то, что я в итоге попробовал, и это сработало 🙂 Спасибо!