Ruby 从块内设置块外变量?
我有以下代码:Ruby 从块内设置块外变量?,ruby,Ruby,我有以下代码: 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
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
所以基本上
read\u char
调用rl\u callback\u read\u char
(gnu readline函数),它在检测到完整的行时调用我安装的处理程序readline\u callback\u callback
,该处理程序调用了用户提供的存储块。解决了问题,而不是范围问题。GNU Readline再次调用我的代码,EOF为NULL,完全忘记了这一点。解决了,不是范围问题。GNU Readline再次在EOF上使用NULL调用我的代码,完全忘记了这一点。您能告诉我们,如何在handler\u install
中调用回调吗?我认为这不是范围问题。试着将block{l|line=l}
改为{l}puts“l={l}”;line=l}
@方兴我修改了我的问题以提供更多的细节扫描你给我们看的,你如何在处理程序{/code>中调用回调?我认为这不是范围问题。尝试将块{l | line=l}
更改为{l | put“l={l}”;line=l}
@方兴我修改了我的问题以提供更多细节
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;
}