2010-05-07 14 views
7

Sto importazione di dati da un file CSV, ho bisogno di lanciare alcuni valori di BigDecimal, e generare un errore se non possono essere analizzati ..Come faccio a sapere se un BigDecimal non è stato analizzato?

Da test, BigDecimal ("numero non valido") restituisce un BigDecimal 0. Questo sarebbe stato ok, ma tipo di disordinato, ad eccezione di un valore valido è 0 ...

Float ("numero non valido") agisce in modo diverso e genera un'eccezione ...

mia soluzione attuale è :

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

Sono assolutamente mancante s omething?

+0

Sono d'accordo con voi, questo è stravagante e incoerente. – jcollum

risposta

2

nel caso semplice è possibile utilizzare RegExp

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

che non era la mia domanda, posso pensare a diversi modi per convalidarlo, ma perché BigDecimal non si comporta come gli altri tipi quando analizza le stringhe –

+0

dalla documentazione: "Il valore iniziale, come una stringa. Gli spazi vengono ignorati, non riconosciuti i caratteri terminano il valore ". Quindi, è una funzione – andrykonchin

+6

@aaz, perché non riconoscere che è un'inconsistenza calva? BigDecimal.new può avere questo comportamento, certo. Ma perché BigDecimal ("blah") non genera un ArgumentError in modo che corrisponda al comportamento di Integer e Float? –

2

mi sono imbattuto in questo comportamento incoerente oggi.

Un approccio:

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

o una versione più robusta:

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 
Problemi correlati