2015-07-04 25 views
-1

當我用非數字輸入測試我的代碼時,Ruby引發了一條默認消息。相反,無論何時發生異常,我都希望我的自定義消息以默認值backtrace.inspect打印。我預計:如何使用自定義錯誤消息

"oops... That was not a number" 

待提高,而不是:

invalid value for Float(): "h\n" (ArgumentError) 

我寫了下面的代碼,由下列文件啓發: stackoverflowrubylearninggithub

class MyCustomError < StandardError 
    def message 
    "oops... That was not a number" 
    end 
end 

def print_a_number 
    begin 
    puts "chose a number" 
    number = Float(gets) 
    raise MyCustomError unless number.is_a? Numeric 
    puts "The number you chose is #{number}" 
    rescue MyCustomError => err 
    puts err.message 
    puts err.backtrace.inspect 
    end 
end 

下面的代碼的行爲與我預期的相反;我不明白爲什麼下面的代碼打印我的默認信息,而上面的代碼沒有:

class MyCustomError < StandardError 
    def message 
    "The file you want to open does not exist" 
    end 
end 

def open_a_file 

    begin 
    puts "What file do you want to open?" 
    file2open = gets.chomp 

    raise MyCustomError unless File.file?(file2open) 

    File.open(file2open, 'r') { |x| 
      while line = x.gets 
       puts line 
      end 
     } 

    rescue MyCustomError => err 
    puts err.message 
    puts err.backtrace.inspect 

    end 
end 
+0

什麼是你的問題? – sawa

回答

0

只需修改您這樣的腳本。

class MyCustomError < StandardError 
    def message 
    "oops... That was not a number" 
    end 
end 

def print_a_number 
    begin 
    puts "chose a number" 
    number = Float(gets) rescue false 
    raise MyCustomError unless number.is_a? Numeric 
    puts "The number you chose is #{number}" 
    rescue MyCustomError => err 
    puts err.message 
    puts err.backtrace.inspect 
    end 
end 
+0

我明白內聯救援代碼的使用:它將解救由Float(獲取)引發的錯誤並返回false(或其他任何東西)。因此,如果我們使用rescue「bad input」而不是rescue false,那麼如果沒有開始 - 救援 - 結束Ruby,它會返回「您選擇的數字爲false」或「您選擇的數字是錯誤的輸入」。隨着開始救援結束的建設,這種情況不會發生,所以我們在內聯救援後似乎是任意的,因爲任何錯誤都會被MyCustomError救起。那麼在這種情況下,內聯救援如何工作呢? – Asarluhi

+0

我不明白你打算說什麼。 「number = Float(gets)rescue false」中的rescue關鍵字可以防止Float方法出現任何可能的解析錯誤,因爲它是begin關鍵字之後唯一可能拋出錯誤的語句。這是一個隱含的救援和使用救援「壞的輸入」不會改變程序的輸出,因爲「糟糕的輸入」.is_a?數字評估爲false。在一個例外之後使用或返回一個合理的值是一個最好的編碼實踐問題,以便知道發生了錯誤的情況而以可接受的方式指導程序的流動。 – Bunti

+0

無論我們在內聯救援後使用「false」還是「true」或任何字符串,在開始救援結束的方法中都不會被Ruby使用,所以看起來似乎。就我所知,任何異常都將由MyCustomError處理。 – Asarluhi

1

unless條件永遠是假的:Kernel#Float要麼拋出一個異常(在這種情況下你的條件不甚至到達)或返回Float(這是Numeric的子類)。

+0

如果except條件被註釋掉,ruby會拋出異常,不管輸入是什麼。如果提高線被全部註釋掉,並且如薩瓦所建議的那樣添加「救助錯誤」,那麼將不會引發任何例外。那麼你會建議使用什麼來代替除非條件?提高看起來有必要,但不能單獨站立 – Asarluhi