2014-02-05 9 views
2

docs에 따르면, Ruby 1.9.2의 아래 예제는 Ruby 1.9.3과 같은 방식으로 작동해야하지만 그렇지 않습니다.Ruby 1.9.2를 사용하는`File.read`의 선택적 인수

루비 1.9.3p484 : 내용 hello있는 파일 test을 감안할 때

File.read "test", 4, :mode => 'rb' 
# => "HELL" 

루비 1.9.2p320

File.read "test", 4, :mode => 'rb' 
# => TypeError: can't convert Hash into Integer 

그것은 루비 1.9.2처럼 보인다 1.9.3이 다를 자신의 선택적 args 처리 방법은 File.read입니다. 왜? 이 변화가 일어난 곳이 어디인지는 알 수 없습니다.

+0

FWIW, 나는이 (루비 1.9.3p286, I386-Cygwin에서/루비 1.9.3p125, I386-mingw32)는 1.9.2에 재현 할 필요가 @FrankSchmitt –

+0

을 재현 할 수없는, 나는 МалъСкрылевъ @ 당신 말이 맞아 –

+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' 
+0

메소드 서명'read (name, [length [, offset]], open_args)'는 기본값이 없으므로,'open_args'를 전달하기 위해서는 이전 값을 앞에 써야합니다. OP가 파일의 처음부터 읽기를 원하기 때문에 '0'은 아마도 오프셋에 대해 수용 가능할 것입니다. –

+0

'nil' 또는 0을 건네 주면 효과가 있을지 모르지만, 왜 * 이것이 * 처음에는 문제가되는지 * 왜 * 분명히 1.9.3에 있지 않은지에 관심이있었습니다. 1.9.2의 버그입니까? – johnrl

0

홀거 (Holger Just)의 답변을 보완하십시오.

소스 코드가 실제로 다른 것처럼 보입니다.

루비 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); 
} 

루비 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); 
} 

그리고 DIFF는이 :

diff

그래서 그들은 실제로 다릅니다.