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