1
我有以下代碼:從塊內部的塊外部設置變量?
def test_callback_interface
with_temp_stdio do |stdin, stdout|
stdin.write("hello\n")
stdin.close
stdout.flush
line = nil
replace_stdio(stdin.path, stdout.path) {
Readline.handler_install("> ", true) { |l| line = l }
6.times { Readline.read_char }
Readline.handler_remove
}
assert_equal("hello", line) <------ FAIL here
assert_equal(true, line.tainted?)
stdout.rewind
assert_equal("> ", stdout.read(2))
assert_equal(1, Readline::HISTORY.length)
assert_equal("hello", Readline::HISTORY[0])
end
assert_equal(true, false)
end
失敗上說,line
是nil
行assert_equal("hello", line)
。不過,我確定該回調被稱爲(我通過將raise
放在那裏來驗證它)。所以我必須在這裏錯過關於示波器基本的東西。有人請指教我如何獲得l
的值到line
變量?
感謝
編輯:
如何調用內部handler_install/read_char回調?
static VALUE readline_callback_ensure(VALUE val) {
free(readline_callback_line);
readline_callback_line = NULL;
return Qnil;
}
static VALUE readline_callback_call(VALUE line) {
VALUE proc = rb_attr_get(mReadline, read_char_cb_proc);
rb_funcall(proc, id_call, 1, line);
return Qnil;
}
static void readline_callback_callback(char * line) {
if (readline_callback_add_history && line) {
add_history(line);
}
readline_callback_line = line;
rb_ensure(
readline_callback_call, line ? rb_str_new_cstr(line) : Qnil,
readline_callback_ensure, Qnil
);
}
static VALUE readline_callback_handler_install(int argc, VALUE * argv, VALUE self) {
VALUE tmp, add_hist, block;
char * prompt = NULL;
rb_need_block();
if (rb_scan_args(argc, argv, "02&", &tmp, &add_hist, &block) > 0) {
prompt = RSTRING_PTR(tmp);
}
if (RTEST(add_hist)) {
readline_callback_add_history = true;
} else {
readline_callback_add_history = false;
}
rb_ivar_set(mReadline, read_char_cb_proc, block);
rl_callback_handler_install(prompt, readline_callback_callback);
return Qnil;
}
static VALUE readline_callback_read_char(VALUE self) {
VALUE proc = rb_attr_get(mReadline, read_char_cb_proc);
if (NIL_P(proc)) {
rb_raise(rb_eRuntimeError, "No handler installed.");
}
rl_callback_read_char();
return Qnil;
}
所以基本上read_char
呼叫rl_callback_read_char
(GNU readline的功能),其在檢測到完整的行調用我的安裝處理程序readline_callback_callback
其中調用存儲由用戶提供的塊。
你能告訴我們,你如何在'handler_install'中調用回調? – fangxing
我不相信這是一個範圍問題。嘗試改變塊'{| l | line = l}'到'{| l |放置「l =#{l}」; line = l}'。 –
@fangxing我修改了我的問題以提供更多詳細信息 – Paladin