Method: Kernel#number_to_human_size
- Defined in:
- lib/quality_extensions/helpers/numbers.rb
#number_to_human_size(number, *args) ⇒ Object
Formats the bytes in size into a more understandable representation (e.g., giving it 1500 yields 1.5 KB). This method is useful for reporting file sizes to users. This method returns nil if size cannot be converted into a number. You can customize the format in the options hash.
Options
-
:base- Pass in 2 (or 1024) to use binary units (KiB, MiB),pass in 10 (or 1000) to use SI (decimal) units (KB, MB) (defaults to base 10). -
:precision- Sets the level of precision (defaults to 1). -
:separator- Sets the separator between the units (defaults to “.”). -
:delimiter- Sets the thousands delimiter (defaults to “”).
Examples
number_to_human_size(123) # => 123 Bytes
number_to_human_size(1234) # => 1.2 KB
number_to_human_size(12345) # => 12.3 KB
number_to_human_size(1234567) # => 1.2 MB
number_to_human_size(1234567890) # => 1.2 GB
number_to_human_size(1234567890123) # => 1.2 TB
number_to_human_size(1234567, :precision => 2) # => 1.23 MB
number_to_human_size(1234567, :precision => 2, :base => 2) # => 1.18 MiB
number_to_human_size(483989, :precision => 0) # => 484 KB
number_to_human_size(483989, :precision => 0, :base => 2) # => 473 KiB
number_to_human_size(1234567, :precision => 2, :separator => ',') # => 1,23 MB
Differences from ActiveSupport version
The ActiveSupport version defaults to binary (base 2) units, while this one
defaults to SI (base 10) units.
The ActiveSupport incorrectly uses KB to refer to binary units, when the correct
abbreviation would be KiB (see http://en.wikipedia.org/wiki/Binary_prefix).
This version has a :base option to let you change the base; the ActiveSupport
version does not.
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/quality_extensions/helpers/numbers.rb', line 142 def number_to_human_size(number, *args) return nil if number.nil? = args. .symbolize_keys! precision ||= ([:precision] || 1) separator ||= ([:separator] || '.') delimiter ||= ([:delimiter] || ',') base ||= ([:base] || 10) # http://en.wikipedia.org/wiki/Binary_prefix if base == 10 || base == 1000 storage_units = %w( Bytes KB MB GB TB ).freeze base = 1000 elsif base == 2 || base == 1024 storage_units = %w( Bytes KiB MiB GiB TiB ).freeze base = 1024 else raise ArgumentError, "base must be 1000 or 1024" end storage_units_format = '%n %u' if number.to_i < base unit = number.to_i == 1 ? 'byte' : 'bytes' storage_units_format.gsub(/%n/, number.to_i.to_s).gsub(/%u/, unit) else max_exp = storage_units.size - 1 number = Float(number) exponent = (Math.log(number) / Math.log(base)).to_i # Convert to base 1024 exponent = max_exp if exponent > max_exp # we need this to avoid overflow for the highest unit number /= base ** exponent unit = storage_units[exponent] begin escaped_separator = Regexp.escape(separator) formatted_number = number_with_precision(number, :precision => precision, :separator => separator, :delimiter => delimiter ).sub(/(\d)(#{escaped_separator}[1-9]*)?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '') storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit) #rescue # number end end end |