File.read not returning nil [newbie]

Hi,

If I run the following code:

# "empty" is a 0-byte file in the current directory

File.open("empty") { |file|
  print "file.read should return nil\n" if file.eof?
  print "file.read: "
  print file.read
  print "\n"
}

read = File.open("empty").read
print "read is NOT nil\n" if read

···

--------------------------------------

I get:

file.read should return nil
file.read: nil
read is NOT nil

This is completely baffling me. Can anyone explain what is going on?
I apologise if this is an obvious question, any pointers would be
appreciated.

Thanks,
Navin.

Navindra Umanee wrote:

file.read should return nil
file.read: nil
read is NOT nil

This is completely baffling me. Can anyone explain what is going on?
I apologise if this is an obvious question, any pointers would be
appreciated.

irb(main):009:0> File.open("NUL") { |f| f.read }
=> ""

It is not returning nil, it returns an empty String instead. Probably best to use p() or IRB when you're checking things like this. There's also File.read(fn) which might help with simplifying code.

Hi Florian,

Thanks a lot for your response!

irb(main):009:0> File.open("NUL") { |f| f.read }
=> ""

It is not returning nil, it returns an empty String instead. Probably
best to use p() or IRB when you're checking things like this. There's
also File.read(fn) which might help with simplifying code.

I am completely confused. The documentation says it should print nil:

http://www.rubycentral.com/book/ref_c_io.html#IO.read

It does return nil in my first test case. It does not return nil in
my second test case which is identical to your test case and as far as
I can see shows the same problem.

So why the difference in behavior? It's still completely baffling me.

Thanks again for your help. I am hoping I can get a proof-of-concept
replacement for dot.kde.org up some time in the distant future. If
it's successful, this would be another high profile site running on
Ruby.

Cheers,
Navin.

···

Florian Gross <flgr@ccan.de> wrote:

Navindra Umanee wrote:

Hi Florian,

Moin.

irb(main):009:0> File.open("NUL") { |f| f.read }
=> ""

I am completely confused. The documentation says it should print nil:

http://www.rubycentral.com/book/ref_c_io.html#IO.read

It does return nil in my first test case. It does not return nil in
my second test case which is identical to your test case and as far as
I can see shows the same problem.

So why the difference in behavior? It's still completely baffling me.

Hm, it seems to return nil when you specify a count (even if you use 0) argument. I'm not sure why it's like that. Maybe matz or somebody else who has knowledge on this could answer...

Thanks again for your help. I am hoping I can get a proof-of-concept
replacement for dot.kde.org up some time in the distant future. If
it's successful, this would be another high profile site running on
Ruby.

That would indeed be very nice. I'm looking forward to this. :slight_smile:

Cheers,
Navin.

Regards,
Florian Gross

Navindra Umanee <navindra@cs.mcgill.ca> writes:

I am completely confused. The documentation says it should print nil:

http://www.rubycentral.com/book/ref_c_io.html#IO.read

It does return nil in my first test case.

It doesn't for me. I get the empty string both times. But why?

It looks like there was a similar discussion in August of 2002

  http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/18089

but I don't know how to read Japanese. Nonetheless, I clearly get a
different result than the one shown there

  $ ruby -e 'p IO.read("/dev/null")'
  ""
  $ ruby -v
  ruby 1.8.2 (2004-12-25) [i686-linux]

It doesn't for me. I get the empty string both times. But why?

I guess that's better than being inconsistent. nil would have been
nicer, IMHO. Do you know if there is a way to make "" equivalent to
nil? I guess I could try messing around with the NilClass.

Just so that I'm clear. You tried this:

File.open("/dev/null") { |file|
  print "file.read should return nil\n" if file.eof?
  print "file.read: "
  print file.read
  print "\n"
}

and got it to print the empty string?

  $ ruby -e 'p IO.read("/dev/null")'
  ""

Same here.

Thanks,
Navin.

···

Tim Heaney <theaney@cablespeed.com> wrote:

In article <35hnlgF4kmpdgU1@individual.net>,
  Florian Gross <flgr@ccan.de> writes:

Hm, it seems to return nil when you specify a count (even if you use 0)
argument. I'm not sure why it's like that. Maybe matz or somebody else
who has knowledge on this could answer...

io.read() and io.read(nil) returns always a string which may be empty.

io.read(n) with 0<n returns a non-empty string or nil.

io.read(0) return "" or nil in Ruby 1.8.
It returns always "" in Ruby 1.9.

···

--
Tanaka Akira

> Thanks again for your help. I am hoping I can get a proof-of-concept
> replacement for dot.kde.org up some time in the distant future. If
> it's successful, this would be another high profile site running on
> Ruby.

That would indeed be very nice. I'm looking forward to this. :slight_smile:

I guess I might as well ask you this here. :slight_smile:

Any idea why the second one fails:

DateTime.strptime('2000-09-28 05:23:01 -0400', '%F %T %z').strftime('%s')

=> "970132981"

DateTime.strptime('970132981', '%s').strftime('%s')

ArgumentError: invalid date
        from /usr/lib/ruby/1.8/date.rb:485:in `new_with_hash'
        from /usr/lib/ruby/1.8/date.rb:495:in `strptime'
        from (irb):31

Thanks!
Navin.

···

Florian Gross <flgr@ccan.de> wrote:

Navindra Umanee <navindra@cs.mcgill.ca> writes:

Just so that I'm clear. You tried this:

File.open("/dev/null") { |file|
  print "file.read should return nil\n" if file.eof?
  print "file.read: "
  print file.read
  print "\n"
}

and got it to print the empty string?

That's right, yes.

  $ cat fileread.rb
  #!/usr/local/bin/ruby -w
  
  File.open("/dev/null") { |file|
    print "file.read should return nil\n" if file.eof?
    print "file.read: "
    print file.read
    print "\n"
  }
  $ ./fileread.rb
  file.read should return nil
  file.read:

Ah, okay. I guess my Ruby is too old:

[vinata] [/tmp] ruby -v
ruby 1.8.0 (2003-08-04) [i586-linux-gnu]

Looks like the behaviour changed in 1.8.1.

Thanks,
Navin.

···

Tim Heaney <theaney@cablespeed.com> wrote:

That's right, yes.