From: Josh Cheek Date: 2009-08-25T03:42:03+09:00 Subject: Re: Array Troubles --000e0cd6cef8c4eaac0471e792da Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit On Mon, Aug 24, 2009 at 3:57 AM, Scott Andrechek wrote: > I've made this small table making program (not reall trademarked) and > have been trying to add the ability to make your own title. Every time > it goes to make the table i get this message: tablemaker.rb:38: > undefined method `rjust' for nil:NilClass (NoMethodError). Here is the > code: > > thisisthewordpage=['page'] > thisisthetitle=[] > tableZZZ=0 > tableZZ=0 > tableZ=0 > pagesZ=0 > pagesZZ=0 > play=true > puts 'Please type your title for your table (if you type nothing the > title will be Table of Contents)' > toptitle=gets.chomp > if toptitle=='' > toptitle='Table of Contents' > thisisthetitle.push toptitle > if toptitle !='' > thisisthetitle.push toptitle > end > end > puts 'Please type your titles in first' > table= [] > while (title=gets.chomp)!= '' > table.push title > tableZ+=1 > end > puts 'Please type your page numbers' > pages= [] > puts table[tableZZZ] > while (page=gets.chomp)!= '' > tableZZZ+=1 > puts table[tableZZZ] > pages.push page > pagesZ+=1 > end > linewidth0=55 > linewidth1=45 > linewidth2=60 > linewidth3=10 > linewidth4=5 > puts (thisisthetitle[0].rjust(linewidth1)) # This is line 38 > while play==true > if tableZ!=0 > puts (table[tableZZ].ljust(linewidth2))+ > (thisisthewordpage[0].rjust(linewidth3)) + '' + > (pages[pagesZZ].rjust(linewidth4)) > tableZ+=-1 > tableZZ+=1 > pagesZ+=-1 > pagesZZ+=1 > if tableZ==0 > play=false > end > end > end > if play==false > puts '' > puts 'Table Created by Table MakerTM' > end > > Any help as always is greatly appreciated. > -Scott Andrechek > -- > Posted via http://www.ruby-forum.com/. > > Hi, Scott, The ruby syntax is if elsif else end In your example, you did if toptitle=='' if toptitle !='' end end So you were actually nesting if statements. However the inner if statement was guaranteed to never be true, because it was the negation of the first if statement. What you could do instead is if toptitle == '' else #by default, this means that toptitle!='' end I refactored the code a bit (I tried not to vary too much from your format). There were some places that were getting a little bit convoluted, keeping track of lots of counters, and incrementing / decrementing them as you went through the array. There were also some variables that I thought would be better off being a different type. I renamed some variables to follow more rubyish conventions. # get the table title puts 'Please type the title for your table (if you type nothing the title will be Table of Contents)' table_title = gets.chomp # not really any need to put this variable into an array table_title = 'Table of Contents' if table_title.empty? #empty string will return true # get the chapter titles, place them into the array # split turns our string into an array, it uses a comma for a delimiter because I passed it # a comma in a string. # map! just loops through each element in the array, and replaces the array element with # the last line of the submitted block. # the ! indicates that it does it to the array we are calling it on. Without the !, it would # return a new array with those elements # the |t| says that we want to access the current element (a title) through a variable named t # strip removes leading and tailing whitespace from a string # documentation for split http://www.ruby-doc.org/core/classes/String.html#M000803 # documentation for map! http://www.ruby-doc.org/core/classes/Array.html#M002190 # documentation for strip http://www.ruby-doc.org/core/classes/String.html#M000820 puts 'Please type your titles in one line, separated by commas.' table = gets.split(',').map!{|t| t.strip} # so this could be expressed in English as "get the next line, # split it into an array of titles, and replace each title in # the array with the same title, after whitespace has been removed" # this is also why we don't have to say gets.chomp, because \n is whitespace # get the page numbers # replace the chapter titles with an array containing the chapter title, and the page number # note that map!{...} and map do ... end can both be used, # I usually use {} for single line blocks, and do end for multi line blocks puts 'Please type your page numbers' table.map! do |chapter_title| print "The page number for " + chapter_title.inspect + " should be: " [chapter_title , gets.chomp] end # initializations for printing out the table # I think a hash makes a lot of sense here, because you were having to remember that specific numbers # correllate to specific places to use the line widths, if we use a hash, we can essentially label which # values are which. For our keys, we use symbols, these are similar to strings, but they all point to # the same object. (you could replace them with strings if it made you feel more comfortable) # documentation for hash http://www.ruby-doc.org/core/classes/Hash.html # documentation for Symbol http://www.ruby-doc.org/core/classes/Symbol.html line_widths = { :table_title => 45 , :chapter_title => 60 , :word_page => 10 , :page_number => 5 } word_page = 'page' # not really any need for this variable to be an array # print out the table title puts puts table_title.rjust( line_widths[:table_title] ) #pull the appropriate width from the hash, notice how #much it looks like accessing an index in an array # print out the table # here we use the each method, which loops through each element in the array # we pass it a block by using do |parameters| ... end # in this case, we are receiving one parameter, the array [chapter_title , page_number] # this was set back when we took the page numbers # we can group our parameters together with () so that this ultimately becomes # chapter_title , page_number = [ "some chapter title" , "12" ] # which is a common Ruby way of assigning values, try it out if you like. table.each do |(chapter_title,page_number)| #when the argument is the last thing on the line, you don't actually need parentheses print chapter_title.ljust line_widths[ :chapter_title ] print word_page.rjust line_widths[ :word_page ] puts page_number.rjust line_widths[ :page_number ] end puts puts 'Table Created by Table MakerTM' # now, for some real fun, you should try turning it into a class ^_^ --000e0cd6cef8c4eaac0471e792da--