2011-05-12 25 views
0

我試圖通過一個Java程序轉換到Ruby學習Ruby的,但我已經來了周圍的代碼塊的錯誤:私有方法要求零'格格」:NilClass(NoMethodError)

def create 
    @user_input = String.new() 
# @word_arr = Array.new 

    print "Enter the text to be converted to pig latin, EOF to quit: " 
    while gets do 
     STDOUT.flush 
     @user_input = gets.chomp 
     @word_arr = @user_input.string.split(' ') 
     @word_arr.each { |x| puts x.engToLatin() + ' '} 
     print "EOF to Quit" 
     @user_input = "" 

    end 

    end 

我已經收到此錯誤:

EnglishToPigLatin.rb:14:in `create': private method `chomp' called for nil:NilClass (NoMethodError) 
    from EnglishToPigLatin.rb:60 

這是圍繞線60區域:

#if __FILE__ == $0 

    mg = EnglishToPigLatin.new 
    mg.create 

#end 

愛喜我試圖做的事情是在仍然有輸入的時候,得到那個輸入,把它分成單獨的單詞,並且通過Pig Latin轉換方法運行每個單詞。

回答

5

它看起來像你試圖讓你的循環內輸入。

嘗試

loop do 
    user_input = gets.chomp! 
    word_arr = user_input.to_s.split(' ') 
    word_arr.each { |x| puts x.engToLatin() + ' '} 
    puts "EOF to Quit" 
end 

否則,你正在試圖獲得輸入的下一行的時候,沒有一個。此外,對於while聲明,do不是必需的。
您也不需要將@user_input重置爲''

而且由於這是一個塊,所以不需要使用實例變量,除非您調用的方法需要它們。

此外,您的條件永遠是真實的。 gets將阻塞,直到它獲得一行輸入。您可以使用loop進行以中斷結束的無限循環。

此外,如果您使用puts代替最後一行代替print,則無需刷新STDOUT

整個事情可能是模塊中的腳本或方法。一個實例甚至不需要被創建。如果你這樣做,而不是使用兩行mg.create,你應該定義一個initialize方法。這是作爲構造函數使用的,並且在創建實例時設置的任何內容都應該放在那裏。

它都是可以做的是這樣的:

loop do 
    puts gets.chomp.split(' ').map{ |x| x.engToLatin() }.join(' ') 
    puts "EOF to Quit" 
end 
+0

這個固定我的電流誤差,但後來留給我的錯誤。我已經更新了我的原始帖子並提供了更多信息 – GeoffB 2011-05-12 17:09:14

+0

你以後得到什麼錯誤? – Mario 2011-05-12 17:11:51

+0

/media/Storage/Documents/Ruby/EnglishToPigLatin.rb:25:未定義的方法'string'用於「test」:字符串(NoMethodError) \t from /media/Storage/Documents/Ruby/EnglishToPigLatin.rb:23:in' loop' \t'from /media/Storage/Documents/Ruby/EnglishToPigLatin.rb:23' 其中23是'loop do' – GeoffB 2011-05-12 17:16:28

2

馬里奧的答案是正確的。但我有以下說明。

  • 您仍然可以使用while構造如下。
  • +' '意味着你不想在每個單詞之後換行。我改變了那部分。 mapjoin在類似情況下很常見。 print不會添加換行符,而puts會執行此操作。
  • 我不確定你想用STDOUT.flush來做什麼。如果您想在每個輸出前滾動到屏幕的頂部,請使用system('clear')
  • 你有一個方法entToLatin,它應該工作,但它是一個ruby約定使用下劃線,如方法eng_to_latin(雖然有一些例外)。

所以更rubyish方法是:

def create 
    print "Enter the text to be converted to pig latin, EOF to quit: " 
    while input = gets.strip and input != 'EOF' 
    system('clear') 
    puts input.split(/\s+/).map{|x| x.engToLatin}.join(' ') 
    puts "EOP to Quit" 
    end 
end 

而且如果你使用Ruby 1.9.2,可以縮短map使:

def create 
    print "Enter the text to be converted to pig latin, EOF to quit: " 
    while input = gets.strip and input != 'EOF' 
    system('clear') 
    puts input.split(/\s+/).map(:engToLatin).join(' ') 
    puts "EOP to Quit" 
    end 
end 
+0

這是一個很好的觀點。 'puts'增加了一個新行,所以@GeoffB應該避免使用它,如果他試圖在一行上打印一個句子。 – Mario 2011-05-12 16:54:41

+0

@Mario是的。 OP需要區分'puts'和'print'。感謝您的評論。 – sawa 2011-05-12 16:56:49

+0

所以'puts'與java的S.O.println相似,而'print'與java的S.O.print相似? – GeoffB 2011-05-12 17:10:53

相關問題