根据docs,我相信下面的例子与Ruby 1.9.2应该像Ruby 1.9.3一样工作,但事实并非如此。给定文件test
,其内容为hello
:
Ruby 1.9.3p484:
File.read "test", 4, :mode => 'rb'
# => "HELL"
Ruby 1.9.2p320
File.read "test", 4, :mode => 'rb'
# => TypeError: can't convert Hash into Integer
Ruby 1.9.2和1.9.3似乎在处理File.read
的可选参数方面有所不同。为什么?我无法弄清楚这个改变是在哪里说的。
答案 0 :(得分:1)
如果你指定长度,Ruby 1.9.2似乎也期望偏移(在相关新闻中,我也可以在1.9.2p320上重现这一点,但不能在1.9.3p484上重现)。从文档和C代码中我不清楚为什么在1.9.2上需要这样做但这不应该是一个太大的问题。
你可以使用nil
传递偏移量,它可以在1.9.3和1.9.2上正常工作。
File.read "test", 4, nil, :mode => 'rb'
答案 1 :(得分:0)
补充Holger Just的答案。
源代码实际上似乎有所不同。
Ruby 1.9.2
static VALUE
rb_io_s_read(int argc, VALUE *argv, VALUE io)
{
VALUE offset;
struct foreach_arg arg;
rb_scan_args(argc, argv, "13", NULL, NULL, &offset, NULL);
open_key_args(argc, argv, &arg);
if (NIL_P(arg.io)) return Qnil;
if (!NIL_P(offset)) {
struct seek_arg sarg;
int state = 0;
sarg.io = arg.io;
sarg.offset = offset;
sarg.mode = SEEK_SET;
rb_protect(seek_before_access, (VALUE)&sarg, &state);
if (state) {
rb_io_close(arg.io);
rb_jump_tag(state);
}
if (arg.argc == 2) arg.argc = 1;
}
return rb_ensure(io_s_read, (VALUE)&arg, rb_io_close, arg.io);
}
Ruby 1.9.3
static VALUE
rb_io_s_read(int argc, VALUE *argv, VALUE io)
{
VALUE opt, offset;
struct foreach_arg arg;
argc = rb_scan_args(argc, argv, "13:", NULL, NULL, &offset, NULL, &opt);
open_key_args(argc, argv, opt, &arg);
if (NIL_P(arg.io)) return Qnil;
if (!NIL_P(offset)) {
struct seek_arg sarg;
int state = 0;
sarg.io = arg.io;
sarg.offset = offset;
sarg.mode = SEEK_SET;
rb_protect(seek_before_access, (VALUE)&sarg, &state);
if (state) {
rb_io_close(arg.io);
rb_jump_tag(state);
}
if (arg.argc == 2) arg.argc = 1;
}
return rb_ensure(io_s_read, (VALUE)&arg, rb_io_close, arg.io);
}
差异是:
所以他们实际上是不同的。