Existe-t-il un moyen de changer le format par défaut des décimales lorsque je les imprime?
irb(main):521:0> pp 10.to_d / 2.5
0.4e1
Je voudrais le formater comme:
irb(main):521:0> pp 10.to_d / 2.5
4.0
Je ne me soucie pas vraiment de la perte de précision potentielle. Le format par défaut est particulièrement ennuyeux à lire lorsque vous imprimez de jolis enregistrements Rails:
<
...
id: 49391,
operator_id: 1,
tax_rate: 0.10e2,
sales_price: 0.1e2,
unit_price: 0.2e1,
>
Je sais que je peux faire to_s
ou to_f
, etc., mais le but de la jolie impression est que je n'ai pas à convertir mes enregistrements avant de pouvoir les jeter un coup d'œil rapide.
3 réponses
Vous pouvez modifier la méthode utilisée par la jolie imprimante. "Normal" IRb utilise inspect
, mais la plupart des bibliothèques de jolies imprimantes ont leurs propres méthodes.
Par exemple, la pp
bibliothèque du la bibliothèque standard utilise une méthode appelée pretty_print
. BigDecimal
n'a pas sa propre implémentation de pretty_print
malheureusement, il hérite simplement de celle de Numeric
qui délègue simplement à inspect
.
Ainsi, nous pouvons écrire le nôtre!
class BigDecimal
def pretty_print(pp)
pp.text to_s('F')
end
end
pp 10.to_d / 2.5
# 4.0
Lorsque vous utilisez to_d
ou to_f
, vous dites à Ruby de convertir la valeur en BigDouble ou Float, mais cela ne spécifie pas le format de sortie, ce qui est un problème différent.
Ruby prend en charge le formatage des chaînes dans quelques saveurs, mais généralement vous définissez un format qui est ensuite utilisé pour "imprimer" la sortie:
foo = 0.4e1
'%1.1f' % foo # => "4.0"
Notez que la sortie est une chaîne, pas un Float ou BigDecimal. Tout est converti en chaîne avant d'être sorti vers la console. Les chaînes de format Ruby suivent les chaînes de format sprintf
utilisées par C, Perl et de nombreux autres langages. Voir sprintf
pour en savoir plus information.
Et, bien que sprintf
existe, je le vois rarement utilisé. Méthode %
de String est utilisé plus souvent, suivi de {{X2} du noyau } méthode.
Notez également que 10.to_d / 2.5
n'est pas valide car 10
est un entier, et Integer ne sait pas comment to_d
:
10.class # => Integer
10.respond_to?(:to_d) # => false
10.to_d / 2.5 # => NoMethodError: undefined method `to_d' for 10:Integer
Exiger BigDecimal est nécessaire pour obtenir to_d
:
require 'bigdecimal'
require 'bigdecimal/util'
10.to_d / 2.5 # => 0.4e1
Dans Ruby 2.4, BigDecimal#inspect
est équivalent à BigDecimal#to_s
qui utilise toujours par défaut la notation scientifique.
decimal = 10.to_d / 2.5
decimal.inspect
# => "0.4e1"
# equivalent to
decimal.to_s
# => "0.4e1"
Heureusement, la classe accepte un argument de sa méthode to_s
qui vous permet de spécifier le format de la chaîne résultante. Entre autres options, vous pouvez spécifier si vous voulez la notation scientifique ou la notation conventionnelle à virgule flottante. Ainsi, en l'utilisant comme suit, vous pouvez obtenir le résultat souhaité:
decimal.to_s("F")
# => "4.0"
La documentation de BigDecimal # to_s explique en détail comment vous pouvez définir d'autres options de formatage.
Malheureusement pour votre cas d'utilisation apparent, il n'y a aucun moyen dans Ruby de changer le format par défaut. Pour obtenir la notation en virgule flottante, vous devez toujours ajouter explicitement l'argument "F"
à la méthode to_s
.
Questions connexes
De nouvelles questions
ruby
Ruby est un langage interprété orienté objet dynamique et open source multi-plateforme. La balise [ruby] est destinée aux questions liées au langage Ruby, y compris sa syntaxe et ses bibliothèques. Les questions Ruby on Rails doivent être marquées avec [ruby-on-rails].