2010-05-07 4 views
7

ich Daten aus einer CSV-Import, ich brauche einige Werte BigDecimal zu werfen, und einen Fehler auslösen, wenn sie nicht analysiert werden können ..Woher weiß ich, ob ein BigDecimal nicht analysiert werden konnte?

Von Tests, BigDecimal („ungültige Nummer“) gibt eine BigDecimal von 0. wäre diese ok, aber irgendwie chaotisch, es sei denn ein gültiger Wert 0 ...

Float („ungültige Nummer“) anders wirkt und eine Ausnahme auslöst ...

Meine aktuelle Lösung ist :

class String 
    def to_bd 
    begin 
     Float(self) 
    rescue 
     raise "Unable to parse: #{self}" 
    end 
    BigDecimal(self) 
    end 
end 

Bin ich total s fehlt etwas?

+0

Ich stimme Ihnen zu, das ist verrückt und inkonsistent. – jcollum

Antwort

2

in einfachen Fall können Sie RegExp

'123.4' =~ /^[+-]{0,1}\d+\.{0,1}\d*$/ 
=> 0 
+0

das war nicht wirklich meine Frage, ich kann mir verschiedene Möglichkeiten vorstellen, es zu validieren, aber warum funktioniert BigDecimal nicht wie die anderen Typen beim Analysieren von Strings –

+0

aus der Dokumentation: "Der Anfangswert, als String. Leerzeichen werden ignoriert, nicht erkannt Zeichen beenden den Wert ". Also, es ist ein Feature – andrykonchin

+6

@aaz komm, warum nicht erkennen, dass es eine Glatze Inkonsistenz ist? BigDecimal.new kann dieses Verhalten haben, sicher. Aber warum löst BigDecimal ("blah") nicht einen ArgumentError aus, der dem Verhalten von Integer und Float entspricht? –

2

verwende ich heute über dieses inkonsistentes Verhalten kam.

Ein Ansatz:

def StrictDecimal(arg) 
    Float(arg) 
    BigDecimal(arg) 
end 

Oder eine robustere Version:

def StrictDecimal(value) 
    if value.is_a?(Float) 
    fail ArgumentError, "innacurate float for StrictDecimal(): #{amount}" 
    end 
    Float(value) 
    BigDecimal(value) 
rescue TypeError 
    fail ArgumentError, "invalid value for StrictDecimal(): #{amount}" 
end