Я немного озадачен тем, как Ruby управляет созданием перечислителей. Блочная итерация имеет смысл и работает для меня; Я до сих пор не понимаю, как возврат Enumerator должен функционировать в коде.
Вот код, с которым я работаю:
VALUE rb_RPRuby_Sender_Kernel_each_backtrace_frame( int argc,
VALUE* args,
VALUE rb_self ) {
rb_thread_t* c_thread = GET_THREAD();
// Get the current frame - we're doing a backtrace, so our current working frame to start is the first previous thread
rb_control_frame_t* c_current_context_frame = RUBY_VM_PREVIOUS_CONTROL_FRAME( RUBY_VM_PREVIOUS_CONTROL_FRAME( c_thread->cfp ) );
// c_top_of_control_frame describes the top edge of the stack trace
// set c_top_of_control_frame to the first frame in <main>
rb_control_frame_t* c_top_of_control_frame = RUBY_VM_NEXT_CONTROL_FRAME( RUBY_VM_NEXT_CONTROL_FRAME( (void *)( c_thread->stack + c_thread->stack_size ) ) );
// for each control frame:
while ( c_current_context_frame < c_top_of_control_frame ) {
VALUE rb_frame_hash = rb_RPRuby_Sender_Kernel_internal_backtraceHashForControlFrame( & c_current_context_frame );
// if we don't have a block, return enumerator
RETURN_ENUMERATOR( rb_self, 0, NULL );
// otherwise, yield the block
rb_yield( rb_frame_hash );
c_current_context_frame = RUBY_VM_PREVIOUS_CONTROL_FRAME( c_current_context_frame );
}
return Qnil;
}
Как будет вызываться последняя строка в цикле while в случае перечислителя?
Должна ли вся моя активность в цикле выполняться перед вызовом RETURN_ENUMERATOR (поскольку RETURN_ENUMERATOR предположительно должен предшествовать rb_yield ())?
Что, если я хочу, чтобы что-то произошло после завершения внутренней итерации? С блоком я могу просто поместить его после цикла while; предположительно, то же самое работает в случае счетчика, но как? Кажется, что каждый раз через цикл он возвращает Enumerator, так как же Enumerator узнает, что нужно вернуть соответствующий соответствующий объект? rb_yield получает rb_frame_hash в качестве переданного аргумента, но RETURN_ENUMERATOR, кажется, принимает аргументы, которые передаются методу, когда перечислитель вызывает метод внутри. Очевидно, что перечислитель вызывает сам метод - возможно, с каким-то внутренним блоком, который просто возвращает экземпляр rb_frame_hash?
Любое понимание внутренних органов приветствуется.
-Asher