Re: ruby woes

Top Page
Attachments:
Message as email
+ (text/plain)
+ (text/html)
+ (text/plain)
Delete this message
Reply to this message
Author: Michael Havens
Date:  
To: Main PLUG discussion list
Subject: Re: ruby woes
Thank you so much for your help guys. Those debugging lessons will prove
invaluable in the future. Thanks for teaching that to me.

On Thu, Dec 29, 2011 at 10:14 AM, Kevin Fries <> wrote:

> 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 <filename>" if filename.nil?
>
> ran again with no parameter:
> ---------------------------------------------------------------------------
> kfries@kfries-laptop:Kevin$ ./sample.rb
> ./sample.rb:4: Missing parameter (RuntimeError)
>
>        Useage: $0 <filename>
> 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 #<File:junk.txt>
> (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")
> => #<File:junk.txt>
> irb(main):002:0> target.size
> NoMethodError: undefined method `size' for #<File:junk.txt>
>        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 <filename>" 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 -
> To subscribe, unsubscribe, or to change your mail settings:
> http://lists.PLUG.phoenix.az.us/mailman/listinfo/plug-discuss
>




--
:-)~MIKE~(-:
---------------------------------------------------
PLUG-discuss mailing list -
To subscribe, unsubscribe, or to change your mail settings:
http://lists.PLUG.phoenix.az.us/mailman/listinfo/plug-discuss