我對Ruby如何處理創建枚舉器有點困惑。基於塊的迭代是有意義的,併爲我工作;我仍然對Enumerator的返回應該如何以代碼方式工作感到困惑。Ruby枚舉和RETURN_ENUMERATOR - 關於Ruby的C內部的問題
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如何知道返回適當的相應對象呢? rb_yield獲取rb_frame_hash作爲傳遞的參數,但是當Enumerator在內部調用方法時,RETURN_ENUMERATOR似乎採用了傳遞給方法的參數。很顯然,Enumerator正在調用這個方法本身 - 可能是通過某種內部塊來簡單地返回rb_frame_hash的實例?
對內部的任何深入瞭解。
-Asher