On Wed, 2011-12-28 at 22:56 -0700, Michael Havens wrote: > I hate it when you are trying to learn something and what you are > learning from is incomplete or wrong. This is the beginning of a ruby > script I am writing which will (in the section shown) erase a file. > ruby tells me that line 15 is wrong! It says: > > ex16.rb:15: undefined local variable or method `file' for > main:Object (NameError) > > I am guessing that what line 15 is doing is telling the program to > make file 'target' smaller but it needs to know how small and the guy > who writes Learn Code the Hard Way forgot to include that in his > tutorial. Or else I'm wrong and in that case please show me where I > am wrong. > > 1 filename = ARGV.first #argument at command line is given a name > 2 script = $0 #script is now titled file's name > 3 > 4 puts "We're going to erase the contents of #{filename}." > 5 puts "If you don't want to do that hit CTRL-C." > 6 puts "If you do want to do that then hit RETURN." > 7 > 8 print "? " > 9 STDIN.gets #it waits for input before going on > 10 > 11 puts "Opening the file..." > 12 target = File.open(filename, 'w') #tells it to open filename or to > write it if non-existant > 13 > ^^^^is this right?^^^^^^^^^^ > 14 puts "Truncating the file. Goodbye!" > 15 target.truncate(target.size) My Diagnostic process: First I input your program without any comments: --------------------------------------------------------------------------- #!/usr/bin/env ruby filename = ARGV.first script = $0 puts "We're going to erase the contents of #{filename}" puts "If you don't want to do that hit CTRL-C" puts "If you want to do that then hit ENTER" print "?" STDIN.gets puts "Opening the file..." target = File.open(filename, 'w') puts "Truncating the file. Goodbye!" target.truncate(target.size) --------------------------------------------------------------------------- Then I ran it without any parameters: --------------------------------------------------------------------------- kfries@kfries-laptop:Kevin$ ./sample.rb We're going to erase the contents of If you don't want to do that hit CTRL-C If you want to do that then hit ENTER ? Opening the file... ./sample.rb:14:in `initialize': can't convert nil into String (TypeError) from ./sample.rb:14:in `open' from ./sample.rb:14 kfries@kfries-laptop:Kevin$ --------------------------------------------------------------------------- OK not good form, added a line after the filename = as such: raise "Missing parameter\n\n\tUseage: $0 " if filename.nil? ran again with no parameter: --------------------------------------------------------------------------- kfries@kfries-laptop:Kevin$ ./sample.rb ./sample.rb:4: Missing parameter (RuntimeError) Useage: $0 kfries@kfries-laptop:Kevin$ --------------------------------------------------------------------------- Much better, always remember, any time you ask for input, then use it (as opposed to press enter to continue), validate it. In this case, I just verified that something was entered, not that it was correct. Next I generated a sample file by doing an ls on /usr/bin, then tried to truncate that file with your program. --------------------------------------------------------------------------- kfries@kfries-laptop:Kevin$ ls /usr/bin > junk.txt kfries@kfries-laptop:Kevin$ ./sample.rb junk.txt We're going to erase the contents of junk.txt If you don't want to do that hit CTRL-C If you want to do that then hit ENTER ? Opening the file... Truncating the file. Goodbye! ./sample.rb:18: undefined method `size' for # (NoMethodError) kfries@kfries-laptop:Kevin$ ls -l total 4 -rw-rw-r-- 1 kfries kfries 0 2011-12-29 09:30 junk.txt -rwxrwxr-x 1 kfries kfries 425 2011-12-29 09:27 sample.rb kfries@kfries-laptop:Kevin$ --------------------------------------------------------------------------- OK, better, it did what it was supposed to do, but then errored out. The error states that the method .size does not exist on the object File. Lets see (using Ruby) what it does support: --------------------------------------------------------------------------- kfries@kfries-laptop:Kevin$ irb irb(main):001:0> target = File.open("junk.txt", "w") => # irb(main):002:0> target.size NoMethodError: undefined method `size' for # from (irb):2 from :0 irb(main):003:0> target.methods => ["stat", "fileno", "find", "inspect", "tty?", "tap", "seek", "<<", "print", "clone", "binmode", "take", "object_id", "__send__", "public_methods", "read_nonblock", "reject", "lines", "ctime", "instance_variable_defined?", "pos", "minmax", "readlines", "freeze", "equal?", "closed?", "member?", "each", "sort", "extend", "partition", "getc", "each_cons", "readbyte", "send", "pos=", "close_read", "any?", "each_with_index", "methods", "lstat", "to_io", "detect", "hash", "putc", "dup", "take_while", "sysseek", "instance_variables", "to_enum", "bytes", "write_nonblock", "collect", "eof", "min_by", "eql?", "reopen", "sort_by", "enum_cons", "ungetc", "group_by", "id", "instance_eval", "truncate", "flock", "close_write", "one?", "enum_with_index", "to_i", "singleton_methods", "each_line", "fsync", "find_index", "puts", "taint", "ioctl", "drop", "instance_variable_get", "frozen?", "enum_for", "chars", "chmod", "readpartial", "map", "display", "instance_of?", "max_by", "method", "syswrite", "grep", "to_a", "flush", "first", "instance_exec", "type", "isatty", "none?", "reverse_each", "protected_methods", "find_all", "each_byte", "atime", "sync", "==", "min", "gets", "===", "eof?", "fcntl", "drop_while", "instance_variable_set", "path", "write", "each_slice", "chown", "sync=", "getbyte", "inject", "respond_to?", "kind_of?", "minmax_by", "close", "to_s", "sysread", "count", "printf", "tell", "class", "zip", "private_methods", "=~", "tainted?", "__id__", "each_char", "mtime", "lineno", "select", "readline", "rewind", "max", "untaint", "nil?", "entries", "pid", "cycle", "enum_slice", "lineno=", "readchar", "reduce", "read", "include?", "is_a?", "all?"] irb(main):004:0> quit kfries@kfries-laptop:Kevin$ --------------------------------------------------------------------------- OK, using IRB, I can confirm that the truncate command should work, and the error message did not indicate a problem with that. It also does not support size, and your error message did indicate that. So, the error message is telling you, that size does not make sense on the File object, and IRB, and the methods command confirms this. So, what should be in there? Well, RubyDoc is your friend, far more than any book can be. I looked up File::truncate for ruby 1.8.7 (the version on my Ubuntu system) at the following URL: http://ruby-doc.org/core-1.8.7/File.html#method-c-truncate And it gave me this: --------------------------------------------------------------------------- truncate(file_name, integer) => 0 Truncates the file file_name to be at most integer bytes long. Not available on all platforms. f = File.new("out", "w") f.write("1234567890") #=> 10 f.close #=> nil File.truncate("out", 5) #=> 0 File.size("out") #=> 5 --------------------------------------------------------------------------- So, it is looking for an integer, to indicate how large you want the file. It also shows the file method being used! So what went wrong??? IRB is showing no size method, and the documents shows it valid? Well, you fell into a common problem of understanding scope. All languages deal with this problem, and it manifests itself in lots of different ways. In this case, size() is a class method, not an instance method. What this means is that, I can call size() against the class, and feed it a filename, but it is not defined in a derived object. So, instead of target.size, use File.size(filename). Making this change the the program gives me this: --------------------------------------------------------------------------- #!/usr/bin/env ruby filename = ARGV.first raise "Missing parameter\n\n\tUseage: $0 " if filename.nil? script = $0 puts "We're going to erase the contents of #{filename}" puts "If you don't want to do that hit CTRL-C" puts "If you want to do that then hit ENTER" print "?" STDIN.gets puts "Opening the file..." target = File.open(filename, 'w') puts "Truncating the file. Goodbye!" target.truncate(File.size(filename)) --------------------------------------------------------------------------- Now lets test it: --------------------------------------------------------------------------- kfries@kfries-laptop:Kevin$ ls /usr/bin > junk.txt kfries@kfries-laptop:Kevin$ ls -la total 36 drwxrwxr-x 2 kfries kfries 4096 2011-12-29 10:00 . drwxrwxrwt 22 root root 4096 2011-12-29 09:46 .. -rw-rw-r-- 1 kfries kfries 22634 2011-12-29 10:02 junk.txt -rwxrwxr-x 1 kfries kfries 433 2011-12-29 10:00 sample.rb kfries@kfries-laptop:Kevin$ ./sample.rb junk.txt We're going to erase the contents of junk.txt If you don't want to do that hit CTRL-C If you want to do that then hit ENTER ? Opening the file... Truncating the file. Goodbye! kfries@kfries-laptop:Kevin$ ls -l total 4 -rw-rw-r-- 1 kfries kfries 0 2011-12-29 10:03 junk.txt -rwxrwxr-x 1 kfries kfries 433 2011-12-29 10:00 sample.rb kfries@kfries-laptop:Kevin$ --------------------------------------------------------------------------- SUCCESS!! I hope seeing me step through the debugging was helpful to you Kevin --------------------------------------------------- PLUG-discuss mailing list - PLUG-discuss@lists.plug.phoenix.az.us To subscribe, unsubscribe, or to change your mail settings: http://lists.PLUG.phoenix.az.us/mailman/listinfo/plug-discuss