Я вижу, что есть относительно новая функция в Ruby, который позволяет цепочечные итерации - другие слова, вместо того, чтобы each_with_indices { |x,i,j| ... }
вы могли бы сделать each.with_indices { |x,i,j| ... }
, где #each
возвращает Enumerator
объект и Enumerator#with_indices
вызывает дополнительные параметры урожайности, которые должны быть включены.Реализации сцепленных итераторов в расширении рубина C
Таким образом, Enumerator
имеет свой собственный метод #with_index
, предположительно для одномерных объектов, source found here. Но я не могу найти лучший способ адаптировать это к другим объектам.
Чтобы был ясен, и в ответ на комментарий: Рубин не имеет #each_with_indices
прямо сейчас - это только получило #each_with_index
. (. Вот почему я хочу создать)
ряд вопросов, которые сами прикованы:
- Как бы один адаптировать цепочечную итерации к один-мерного объекта? Просто сделайте
include Enumerable
? - Предположительно вышеприведенное (№ 1) не будет работать для n -мерный объект. Будет ли создан класс
EnumerableN
, полученный отEnumerable
, но с#with_index
преобразован в#with_indices
? - Может ли # 2 быть сделано для расширений Ruby, написанных на C? Например, у меня есть класс матрицы, в котором хранятся различные типы данных (поплавки, двойники, целые числа, иногда обычные объекты Ruby, и т. Д.). Перечисление должно сначала проверить тип данных (
dtype
) в соответствии с приведенным ниже примером.
Пример:
VALUE nm_dense_each(VALUE nm) {
volatile VALUE nm = nmatrix; // Not sure this actually does anything.
DENSE_STORAGE* s = NM_STORAGE_DENSE(nm); // get the storage pointer
RETURN_ENUMERATOR(nm, 0, 0);
if (NM_DTYPE(nm) == nm::RUBYOBJ) { // matrix stores VALUEs
// matrix of Ruby objects -- yield those objects directly
for (size_t i = 0; i < nm_storage_count_max_elements(s); ++i)
rb_yield(reinterpret_cast<VALUE*>(s->elements)[i]);
} else { // matrix stores non-Ruby data (int, float, etc)
// We're going to copy the matrix element into a Ruby VALUE and then operate on it. This way user can't accidentally
// modify it and cause a seg fault.
for (size_t i = 0; i < nm_storage_count_max_elements(s); ++i) {
// rubyobj_from_cval() converts any type of data into a VALUE using macros such as INT2FIX()
VALUE v = rubyobj_from_cval((char*)(s->elements) + i*DTYPE_SIZES[NM_DTYPE(nm)], NM_DTYPE(nm)).rval;
rb_yield(v); // yield to the copy we made
}
}
}
Таким образом, чтобы объединить свои три вопроса в одном: Как бы я пишу, в C, а #with_indices
к цепи на NMatrix#each
выше способом?
Я не особо хочу, чтобы кто-то чувствовал, что я прошу их закодировать это для меня, хотя, если бы вы этого захотели, мы бы хотели, чтобы вы участвовали в нашем проекте. =)
Но если вы знаете какой-то пример в Интернете о том, как это делается, это было бы идеально - или если бы вы могли просто объяснить словами, это тоже было бы прекрасно.
Нет такой функции. Ничто, как вы упоминаете, не существует в Ruby 1.9. И ни одна такая вещь, как вы упомянули, не была представлена в Ruby 2.0. Однако Ruby имеет другую вещь, называемую 'each_with_index'. И Ruby 1.9 представил 'with_index'. – sawa
Хорошо, исправил мой вопрос - теперь он общий для Руби. Вы спустили вниз? Могу я спросить, почему? Это довольно тщательно написанный вопрос. –
@sawa: Он не спрашивает о функциях Ruby. Это вопрос высокого уровня, он является разработчиком, вероятно, частью команды NMatrix, и он в основном спрашивает, что такое Ruby-метод написания Ruby-методов в C :-) Я (сейчас) пользователь Matc-Andre's Matrix и Я рад, что NMATrix arround в качестве альтернативы. –