Class: ByteSize
- Inherits:
-
Object
- Object
- ByteSize
- Includes:
- Comparable
- Defined in:
- lib/bytesize.rb,
lib/bytesize/version.rb,
lib/bytesize/activerecord.rb
Overview
This class is used to represent a size in bytes.
It uses the SI standard unit symbols: kB, MB, GB, TB, PB, EB, ZB, YB.
For a version that uses the IEC standard unit symbols, see IECByteSize[IECByteSize.html].
Examples of use
ByteSize.new( 4127 ) #=> (4.13 kB)
ByteSize.new( "22 GB" ) #=> (22 GB)
ByteSize.new( "22 GiB" ) #=> (23.62 GB)
ByteSize.bytes( 42 ) #=> (42 bytes)
ByteSize.kb( 42 ) #=> (42 kB)
ByteSize.mb( 42 ) #=> (42 MB)
ByteSize.gb( 42 ) #=> (42 GB)
ByteSize.tb( 42 ) #=> (42 TB)
ByteSize.pb( 42 ) #=> (42 PB)
ByteSize.eb( 42 ) #=> (42 EB)
ByteSize.zb( 42 ) #=> (42 ZB)
ByteSize.yb( 42 ) #=> (42 YB)
Conversion of values:
ByteSize.gb( 100 ).to_gib #=> 93.13225746154785
ByteSize.gib( 2.42 ).to_mib #=> 2478.079999923706
With numeric convenience methods:
require 'bytesize/unit'
100.gb.to_gib #=> 93.13225746154785
2.42.gib.to_mib #=> 2478.079999923706
Direct Known Subclasses
Defined Under Namespace
Classes: ActiveRecordType
Constant Summary collapse
- SI_BASE =
:stopdoc:
1000
- SI_ORDERS_OF_MAGNITUDE =
{ kB: SI_BASE, MB: SI_BASE**2, GB: SI_BASE**3, TB: SI_BASE**4, PB: SI_BASE**5, EB: SI_BASE**6, ZB: SI_BASE**7, YB: SI_BASE**8 }
- SI_UNIT_SYMBOLS =
SI_ORDERS_OF_MAGNITUDE.keys.freeze
- IEC_BASE =
1024
- IEC_ORDERS_OF_MAGNITUDE =
{ KiB: IEC_BASE, MiB: IEC_BASE**2, GiB: IEC_BASE**3, TiB: IEC_BASE**4, PiB: IEC_BASE**5, EiB: IEC_BASE**6, ZiB: IEC_BASE**7, YiB: IEC_BASE**8 }
- IEC_UNIT_SYMBOLS =
IEC_ORDERS_OF_MAGNITUDE.keys.freeze
- ALL_ORDERS_OF_MAGNITUDE =
SI_ORDERS_OF_MAGNITUDE.merge(IEC_ORDERS_OF_MAGNITUDE).freeze
- ALL_UNIT_SYMBOLS =
ALL_ORDERS_OF_MAGNITUDE.keys.freeze
- BASE =
SI_BASE
- UNIT_SYMBOLS =
SI_UNIT_SYMBOLS
- ORDERS_OF_MAGNITUDE =
SI_ORDERS_OF_MAGNITUDE
- BYTES_REGEX =
:stopdoc:
/\A\s*(\-?[0-9]+)\s*(bytes)?\s*\z/.freeze
- SI_REGEX =
/\A\s*(\-?[0-9]+(\.[0-9]+)?)\s*(#{ SI_UNIT_SYMBOLS.join('|') })\s*\z/i.freeze
- IEC_REGEX =
/\A\s*(\-?[0-9]+(\.[0-9]+)?)\s*(#{ IEC_UNIT_SYMBOLS.join('|') })\s*\z/i.freeze
- VERSION =
'0.1.2'.freeze
Instance Attribute Summary collapse
-
#bytes ⇒ Object
(also: #to_bytes)
:stopdoc:.
Class Method Summary collapse
-
.bytes(b) ⇒ Object
:call-seq: ByteSize.bytes( n ) -> bytesize.
-
.new(val) ⇒ Object
:stopdoc:.
-
.parse(val) ⇒ Object
call-seq: ByteSize.parse( string ) -> bytesize.
Instance Method Summary collapse
-
#%(val) ⇒ Object
:call-seq: bytesize % val -> bytesize.
-
#*(val) ⇒ Object
:call-seq: bytesize * val -> bytesize.
-
#**(pow) ⇒ Object
:call-seq: bytesize ** pow -> bytesize.
-
#+(val) ⇒ Object
:call-seq: bytesize + val -> bytesize.
-
#+@ ⇒ Object
:call-seq: +bytesize -> bytesize.
-
#-(val) ⇒ Object
:call-seq: bytesize - val -> bytesize.
-
#-@ ⇒ Object
:call-seq: -bytesize -> bytesize.
-
#/(val) ⇒ Object
:call-seq: bytesize / val -> bytesize or float.
-
#<(other) ⇒ Object
:call-seq: bytesize < val -> true or false.
-
#<=(other) ⇒ Object
:call-seq: bytesize <= val -> true or false.
-
#<=>(other) ⇒ Object
:call-seq: bytesize <=> other -> -1, 0, 1, or nil.
-
#==(other) ⇒ Object
(also: #===)
:call-seq: bytesize == other -> true or false.
-
#>(other) ⇒ Object
:call-seq: bytesize > val -> true or false.
-
#>=(other) ⇒ Object
:call-seq: bytesize >= val -> true or false.
-
#coerce(other) ⇒ Object
:stopdoc:.
-
#eql?(other) ⇒ Boolean
:call-seq: eql?( other_bytesize ) -> true or false.
-
#hash ⇒ Object
:stopdoc:.
-
#initialize(bytes) ⇒ ByteSize
constructor
call-seq: new( integer ) new( string ).
-
#inspect ⇒ Object
:call-seq: inspect -> string.
-
#negative? ⇒ Boolean
:call-seq: negative? -> true or false.
-
#positive? ⇒ Boolean
:call-seq: positive? -> true or false.
-
#to_i ⇒ Object
:call-seq: to_i -> integer.
-
#to_iec ⇒ Object
:call-seq: to_iec -> iecbytesize.
-
#to_s(decimal_places = nil) ⇒ Object
:call-seq: to_s -> string to_s( decimal_places ) -> string.
-
#to_si ⇒ Object
:call-seq: to_si -> bytesize.
-
#zero? ⇒ Boolean
:call-seq: zero? -> true or false.
Constructor Details
Instance Attribute Details
#bytes ⇒ Object Also known as: to_bytes
:stopdoc:
881 882 883 |
# File 'lib/bytesize.rb', line 881 def bytes @bytes end |
Class Method Details
.bytes(b) ⇒ Object
152 153 154 155 |
# File 'lib/bytesize.rb', line 152 def self.bytes( b ) raise( TypeError, "expected #{Numeric}, got #{b.class}" ) unless b.is_a?(Numeric) self.new( b.round ) end |
.new(val) ⇒ Object
:stopdoc:
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 |
# File 'lib/bytesize.rb', line 345 def self.new( val ) case val when ByteSize super( val.bytes ) when Integer super( val ) when String if m = val.match(BYTES_REGEX) super( m[1].to_i ) elsif m = val.match(SI_REGEX) self.send( m[3].downcase.to_sym, m[2].nil? ? m[1].to_i : m[1].to_f ) elsif m = val.match(IEC_REGEX) self.send( m[3].downcase.to_sym, m[2].nil? ? m[1].to_i : m[1].to_f ) else raise( ArgumentError, "invalid #{self} string: #{val.inspect}" ) end else raise( TypeError, "no implicit conversion of #{val.class} into #{self}" ) end end |
.parse(val) ⇒ Object
call-seq:
ByteSize.parse( string ) -> bytesize
Parses a String into either a ByteSize or IECByteSize depending on it’s unit symbol.
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
# File 'lib/bytesize.rb', line 326 def self.parse( val ) if val.is_a?(String) if m = val.match(BYTES_REGEX) ByteSize.new( m[1].to_i ) elsif m = val.match(SI_REGEX) ByteSize.send( m[3].downcase.to_sym, m[2].nil? ? m[1].to_i : m[1].to_f ) elsif m = val.match(IEC_REGEX) IECByteSize.send( m[3].downcase.to_sym, m[2].nil? ? m[1].to_i : m[1].to_f ) else raise( ArgumentError, "invalid #{ByteSize} or #{IECByteSize} string: #{val.inspect}" ) end else raise( TypeError, "expected #{String}, got #{val.class}" ) end end |
Instance Method Details
#%(val) ⇒ Object
643 644 645 646 647 648 649 650 651 652 653 654 655 |
# File 'lib/bytesize.rb', line 643 def %( val ) case val when Numeric self.class.new(( bytes % val ).round) when ByteSize self.class.new( bytes % val.bytes ) else raise( TypeError, "#{val.class} can't be coerced into #{self.class}" ) end end |
#*(val) ⇒ Object
668 669 670 671 672 673 674 675 676 677 678 679 680 |
# File 'lib/bytesize.rb', line 668 def *( val ) case val when Numeric self.class.new(( bytes * val ).round) when ByteSize raise( TypeError, "cannot multiply #{ByteSize} with #{val.class}" ) else raise( TypeError, "#{val.class} can't be coerced into #{self.class}" ) end end |
#**(pow) ⇒ Object
693 694 695 696 697 698 699 700 701 702 703 704 705 |
# File 'lib/bytesize.rb', line 693 def **( pow ) case pow when Numeric self.class.new(( bytes ** pow ).round) when ByteSize raise( TypeError, "cannot raise #{ByteSize} to a power of #{pow.class}" ) else raise( TypeError, "#{pow.class} can't be coerced into #{self.class}" ) end end |
#+(val) ⇒ Object
717 718 719 720 721 722 723 724 725 726 727 728 729 |
# File 'lib/bytesize.rb', line 717 def +( val ) case val when Numeric self.class.new(( bytes + val ).round) when ByteSize self.class.new( bytes + val.bytes ) else raise( TypeError, "#{val.class} can't be coerced into #{self.class}" ) end end |
#+@ ⇒ Object
:call-seq:
+bytesize -> bytesize
Unary Plus — Returns the receiver’s value.
739 740 741 |
# File 'lib/bytesize.rb', line 739 def +@ self end |
#-(val) ⇒ Object
753 754 755 756 757 758 759 760 761 762 763 764 765 |
# File 'lib/bytesize.rb', line 753 def -( val ) case val when Numeric self.class.new(( bytes - val ).round) when ByteSize self.class.new( bytes - val.bytes ) else raise( TypeError, "#{val.class} can't be coerced into #{self.class}" ) end end |
#-@ ⇒ Object
:call-seq:
-bytesize -> bytesize
Unary Minus — Returns the receiver’s value, negated.
775 776 777 |
# File 'lib/bytesize.rb', line 775 def -@ self.class.new( 0 - bytes ) end |
#/(val) ⇒ Object
792 793 794 795 796 797 798 799 800 801 802 803 804 |
# File 'lib/bytesize.rb', line 792 def /( val ) case val when Numeric self.class.new(( bytes / val ).round) when ByteSize bytes.to_f / val.bytes.to_f else raise( TypeError, "#{val.class} can't be coerced into #{self.class}" ) end end |
#<(other) ⇒ Object
:call-seq:
bytesize < val -> true or false
Returns true
if the value of bytesize is less than that of val.
553 554 555 556 557 558 559 560 561 562 563 564 565 |
# File 'lib/bytesize.rb', line 553 def <( other ) case other when ByteSize bytes < other.bytes when Numeric bytes < other else raise( ArgumentError, "comparison of #{self.class} with #{other.inspect} failed" ) end end |
#<=(other) ⇒ Object
:call-seq:
bytesize <= val -> true or false
Returns true
if the value of bytesize is less than or equal to that of val.
575 576 577 578 579 580 581 582 583 584 585 586 587 |
# File 'lib/bytesize.rb', line 575 def <=( other ) case other when ByteSize bytes <= other.bytes when Numeric bytes <= other else raise( ArgumentError, "comparison of #{self.class} with #{other.inspect} failed" ) end end |
#<=>(other) ⇒ Object
:call-seq:
bytesize <=> other -> -1, 0, 1, or nil
Compares bytesize to other and returns 0
if they are equal, -1
if bytesize is less than other, or 1
if bytesize is greater than other.
Returns nil
if the two values are incomparable.
818 819 820 821 822 823 824 825 826 827 828 829 830 |
# File 'lib/bytesize.rb', line 818 def <=>( other ) case other when Numeric bytes <=> other when ByteSize bytes <=> other.bytes else nil end end |
#==(other) ⇒ Object Also known as: ===
:call-seq:
bytesize == other -> true or false
Returns true
if bytesize is equal to other.
If other is not an instance of ByteSize an attempt will be made to convert it to one.
842 843 844 845 846 847 848 849 850 851 852 853 854 |
# File 'lib/bytesize.rb', line 842 def ==( other ) case other when Numeric bytes == other when ByteSize bytes == other.bytes else false end end |
#>(other) ⇒ Object
:call-seq:
bytesize > val -> true or false
Returns true
if the value of bytesize is greater than that of val.
597 598 599 600 601 602 603 604 605 606 607 608 609 |
# File 'lib/bytesize.rb', line 597 def >( other ) case other when ByteSize bytes > other.bytes when Numeric bytes > other else raise( ArgumentError, "comparison of #{self.class} with #{other.inspect} failed" ) end end |
#>=(other) ⇒ Object
:call-seq:
bytesize >= val -> true or false
Returns true
if the value of bytesize is greater than or equal to that of val.
619 620 621 622 623 624 625 626 627 628 629 630 631 |
# File 'lib/bytesize.rb', line 619 def >=( other ) case other when ByteSize bytes >= other.bytes when Numeric bytes >= other else raise( ArgumentError, "comparison of #{self.class} with #{other.inspect} failed" ) end end |
#coerce(other) ⇒ Object
:stopdoc:
887 888 889 890 891 892 893 894 895 896 897 |
# File 'lib/bytesize.rb', line 887 def coerce( other ) if Numeric [ other, self.to_i ] else begin [ self.class.new(other), self ] rescue raise( TypeError, "#{other.class} can't be coerced into #{self.class}" ) end end end |
#eql?(other) ⇒ Boolean
:call-seq:
eql?( other_bytesize ) -> true or false
Returns true
if the ByteSize is equal to other_bytesize.
908 909 910 |
# File 'lib/bytesize.rb', line 908 def eql?( other ) other.class == self.class && other.bytes == bytes end |
#hash ⇒ Object
:stopdoc:
915 916 917 |
# File 'lib/bytesize.rb', line 915 def hash bytes.hash end |
#inspect ⇒ Object
932 933 934 |
# File 'lib/bytesize.rb', line 932 def inspect sprintf( '(%s)', to_s ) end |
#negative? ⇒ Boolean
944 945 946 |
# File 'lib/bytesize.rb', line 944 def negative? bytes < 0 end |
#positive? ⇒ Boolean
956 957 958 |
# File 'lib/bytesize.rb', line 956 def positive? bytes > 0 end |
#to_i ⇒ Object
982 983 984 |
# File 'lib/bytesize.rb', line 982 def to_i bytes.to_i end |
#to_iec ⇒ Object
:call-seq:
to_iec -> iecbytesize
Returns the size as an instance of IECByteSize.
If called on an instance of IECByteSize it returns self
.
996 997 998 |
# File 'lib/bytesize.rb', line 996 def to_iec self.class == IECByteSize ? self : IECByteSize.new(self.to_i) end |
#to_s(decimal_places = nil) ⇒ Object
:call-seq:
to_s -> string
to_s( decimal_places ) -> string
Format this ByteSize as a String.
The second form formats it with exactly decimal_places decimal places.
Example:
ByteSize.bytes(3000000000000).to_s #=> "3 TB"
ByteSize.bytes(2460000000000).to_s #=> "2.46 TB"
ByteSize.bytes(3000000000000).to_s(2) #=> "3.00 TB"
ByteSize.bytes(1234567890000).to_s(2) #=> "1.23 TB"
ByteSize.bytes(1234567890000).to_s(4) #=> "1.2346 TB"
1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 |
# File 'lib/bytesize.rb', line 1020 def to_s( decimal_places=nil ) unless decimal_places.nil? raise( TypeError, "expected #{Integer}, got #{decimal_places.class}" ) unless decimal_places.is_a?(Integer) raise( RangeError, "decimal places cannot be negative" ) unless decimal_places >= 0 end b = bytes.abs scale = self.class::ORDERS_OF_MAGNITUDE.sort{|(ak,av),(bk,bv)| av <=> bv } if b == 0 unit = scale.first else unit = scale.find_index{|k,v| v > b } if unit.nil? unit = scale.last else unit = scale[unit-1] end end if decimal_places.nil? sprintf( negative? ? '-%g %s' : '%g %s', ((b/Float(unit.last))*100).round/100.0, unit.first.to_s ) else sprintf( negative? ? "-%.0#{decimal_places}f %s" : "%.0#{decimal_places}f %s", b / Float(unit.last), unit.first.to_s ) end end |
#to_si ⇒ Object
1058 1059 1060 |
# File 'lib/bytesize.rb', line 1058 def to_si self.class == ByteSize ? self : ByteSize.new(self.to_i) end |
#zero? ⇒ Boolean
1070 1071 1072 |
# File 'lib/bytesize.rb', line 1070 def zero? bytes == 0 end |