I fixed this - but why does it work?

I am doing an exercise in a tutorial, which is to get this code to run:

1 filename = ARGV.first
2 script = $0
3
4 puts "We're going to erase #{filename}."
5 puts "If you don't want that, hit CTRL-C (^C)."
6 puts "If you do want that, hit RETURN."
7
8 print "? "
9 STDIN.gets
10
11 puts "Opening the file..."
12 target = File.open(filename, 'w')
13
14 puts "Truncating the file. Goodbye!"
15 target.truncate(target.size)
16
17 puts "Now I'm going to ask you for three lines."
18
19 print "line 1: "; line1 = STDIN.gets.chomp()
20 print "line 2: "; line2 = STDIN.gets.chomp()
21 print "line 3: "; line3 = STDIN.gets.chomp()
22
23 puts "I'm going to write these to the file."
24
25 target.write(line1)
26 target.write("\n")
27 target.write(line2)
28 target.write("\n")
29 target.write(line3)
30 target.write("\n")
31
32 puts "And finally, we close it."
33 target.close()

when I tried to run the above I got a No Method Error for size on line
15.

After some experimentation I got the following to run apparently as
expected:

filename = ARGV.first

script = $0

puts "We're going to erase #{filename}."

puts "If you don't want that, hit CTRL-C (^C)."

puts "If you do want that, hit RETURN."

print "? "

STDIN.gets

puts "Opening the file..."

target = File.open(filename, 'w')

puts "Truncating the file. Goodbye!"

flength=File.size(target)
target.truncate(flength)

puts "Now I'm going to ask you for three lines."

print "line 1: "; line1 = STDIN.gets.chomp()

print "line 2: "; line2 = STDIN.gets.chomp()

print "line 3: "; line3 = STDIN.gets.chomp()

puts "I'm going to write these to the file."

target.write(line1)

target.write("\n")

target.write(line2)

target.write("\n")

target.write(line3)

target.write("\n")

puts "And finally, we close it."

target.close()

So why does the file with my change work? Or, if you prefer, why did the
original give a NoMethodError?

···

--
Posted via http://www.ruby-forum.com/.

probably, because File.size(target) calls the *class method* which is
defined for File class, while target.size calls an *instance method*
which is not defined for File class.

···

--
Posted via http://www.ruby-forum.com/.

I appreciate the help so far. I tried it in Windows under Cygwin and in
Ubuntu with similar results. I just ruby -v'd and got 1.8.7, so
installed 1.9.1 and then tried the the original version using the
command ruby1.9.1. I am sure this surprises no one but me, but it worked
like a charm.

···

--
Posted via http://www.ruby-forum.com/.

That's what I assumed too ... (based on the printed documentation in
"Programming Ruby 1.9" Pick Axe which only lists the ). But it turns out
both the instance methods and the class method (both on file name
and File object) work.

Also, trying a case where the file could not be created (forced with an
access permission denied) gives another Exception.

So, I cannot reproduce the original problem here ... (on Linux)

peterv@ASUS:~$ ls -lrt | tail -3
---------- 1 peterv peterv 0 2011-10-17 00:39 do_not_edit
-rw-r--r-- 1 peterv peterv 12 2011-10-17 00:41 test123
-rw-r--r-- 1 peterv peterv 9 2011-10-17 00:42 test
peterv@ASUS:~$ ruby -v
ruby 1.9.2p290 (2011-07-09 revision 32553) [i686-linux]
peterv@ASUS:~$ irb
001:0> f = File.open("test", 'w')
=> #<File:test>
002:0> # open for write resets the size to 0
003:0* ^C
003:0> f.size
=> 0
004:0> f2 = File.open("test123", 'r')
=> #<File:test123>
005:0> f2.size
=> 12
006:0> File.size(f2)
=> 12
007:0> File.size("test123")
=> 12
008:0> File.open('do_not_edit', 'w')
Errno::EACCES: Permission denied - do_not_edit
from (irb):8:in `initialize'
from (irb):8:in `open'
from (irb):8
from /home/peterv/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'

HTH,

Peter

···

On Mon, Oct 17, 2011 at 12:35 AM, Sub Zero <zhoran@inbox.ru> wrote:

probably, because File.size(target) calls the *class method* which is
defined for File class, while target.size calls an *instance method*
which is not defined for File class.

OK, that explains. In ruby 1.8.7 it works as documented in the
Pick Axe book (only class method on File, no instance method).

Thanks for clearing that out :slight_smile:

<code>
peterv@ASUS:~$ rvm use 1.8.7-p334
Using /home/peterv/.rvm/gems/ruby-1.8.7-p334

peterv@ASUS:~$ ruby -v
ruby 1.8.7 (2011-02-18 patchlevel 334) [i686-linux]

peterv@ASUS:~$ irb
001:0> f1 = File.open('test','w')
=> #<File:test>
002:0> f1.size
NoMethodError: undefined method `size' for #<File:test>
from (irb):2
003:0> File.size("test") # as documented in Pick Axe
=> 0
004:0> File.size(f1)
=> 0
</code>

Peter

···

On Mon, Oct 17, 2011 at 1:52 AM, Edwin G. <edwin.galloway@gmail.com> wrote:

I appreciate the help so far. I tried it in Windows under Cygwin and in
Ubuntu with similar results. I just ruby -v'd and got 1.8.7,