Module: EasyAttributes::FixedPoint
- Defined in:
- lib/easy_attributes.rb
Overview
Private Module: FixedPoint handles integer<->fixed-point numbers Fixed-Point rules are a hash of these values
:units Use this as an alternative suffix name to the money methods ('dollars' gives 'xx_dollars')
:precision The number of digits implied after the decimal, default is 2
:separator The character to use after the integer part, default is '.'
:delimiter The character to use between every 3 digits of the integer part, default none
:positive The sprintf format to use for positive numbers, default is based on precision
:negative The sprintf format to use for negative numbers, default is same as :positive
:zero The sprintf format to use for zero, default is same as :positive
:nil The sprintf format to use for nil values, default none
:unit Prepend this to the front of the money value, say '$', default none
:blank Return this value when the money string is empty or has no digits on assignment
:negative_regex A Regular Expression used to determine if a number is negative (and without a - sign)
Class Method Summary collapse
-
.fixed_point_to_integer(value, *args) ⇒ Object
Private: Takes a string of a fixed-point representation (from editing) and converts it to the integer representation according to the passed rules hash rules - hash of fixed-point conversion rules.
-
.float_to_integer(value, *args) ⇒ Object
Returns the integer (cents) value from a Float rules - hash of fixed-point conversion rules.
-
.format_fixed_point(value, pattern = "%.2m", *args) ⇒ Object
Replacing the sprintf function to deal with money as float.
-
.integer_to_fixed_point(value, *args) ⇒ Object
Private: Formats an integer value as the defined fixed-point representation value - integer representation of number rules - hash of fixed-point conversion rules.
-
.integer_to_float(value, *args) ⇒ Object
Private: Converts the integer into a float value with the given fixed-point definition.
Class Method Details
.fixed_point_to_integer(value, *args) ⇒ Object
Private: Takes a string of a fixed-point representation (from editing) and converts it to the integer representation according to the passed rules hash rules - hash of fixed-point conversion rules
Returns the integer of the given money string. Uses relevant options from #easy_money
617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 |
# File 'lib/easy_attributes.rb', line 617 def self.fixed_point_to_integer(value, *args) opt = args.last.is_a?(Hash) ? args.pop : {} value = value.to_s value = value.gsub(opt[:delimiter],'') if opt[:delimiter] value = value.gsub(opt[:separator],'.') if opt[:separator] value = value.gsub(/^[^\d\.\-\,]+/,'') return (opt[:blank]||nil) unless value =~ /\d/ m = value.to_s.match(opt[:negative_regex]||/^(-?)(.+\d)\s*cr/i) value = value.match(/^-/) ? m[2] : "-#{m[2]}" if m && m[2] # Money string ("123.45") to proper integer withough passing through the float transformation match = value.match(/(-?\d*)\.?(\d*)/) return 0 unless match value = match[1].to_i * (10 ** (opt[:precision]||2)) cents = match[2] cents = cents + '0' while cents.length < (opt[:precision]||2) cents = cents.to_s[0,opt[:precision]||2] value += cents.to_i * (value<0 ? -1 : 1) value end |
.float_to_integer(value, *args) ⇒ Object
Returns the integer (cents) value from a Float rules - hash of fixed-point conversion rules
640 641 642 643 644 |
# File 'lib/easy_attributes.rb', line 640 def self.float_to_integer(value, *args) opt = args.last.is_a?(Hash) ? args.pop : {} return (opt[:blank]||nil) if value.nil? value = (value.to_f*(10**((opt[:precision]||2)+1))).to_i/10 # helps rounding 4.56 -> 455 ouch! end |
.format_fixed_point(value, pattern = "%.2m", *args) ⇒ Object
Replacing the sprintf function to deal with money as float. “… %[flags]m …” rules - hash of fixed-point conversion rules
648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 |
# File 'lib/easy_attributes.rb', line 648 def self.format_fixed_point(value, pattern="%.2m", *args) opt = args.last.is_a?(Hash) ? args.pop : {} sign = value < 0 ? -1 : 1 dollars, cents = value.abs.divmod( 10 ** (opt[:precision]||2)) dollars *= sign parts = pattern.match(/^(.*)%([-\. \d+]*)[fm](.*)/) return pattern unless parts intdec = parts[2].match(/(.*)\.(\d*)/) dprec, cprec = intdec ? [intdec[1], intdec[2]] : ['', ''] dollars = sprintf("%#{dprec}d", dollars) cents = '0' + cents.to_s while cents.to_s.length < (opt[:precision]||2) cents = cents.to_s[0,cprec.to_i] cents = cents + '0' while cents.length < cprec.to_i value = parts[1] + "#{(dollars.to_i==0 && sign==-1) ? '-' : '' }#{dollars}#{cents>' '? '.':''}#{cents}" + parts[3] value end |
.integer_to_fixed_point(value, *args) ⇒ Object
Private: Formats an integer value as the defined fixed-point representation value - integer representation of number rules - hash of fixed-point conversion rules
Returns the fixed-point representation as a string for editing
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 |
# File 'lib/easy_attributes.rb', line 573 def self.integer_to_fixed_point(value, *args) opt = args.last.is_a?(Hash) ? args.pop : {} opt[:positive] ||= "%.#{opt[:precision]||2}f" pattern = if value.nil? value = 0 opt[:nil] || opt[:positive] else case value <=> 0 when 1 then opt[:positive] when 0 then opt[:zero] || opt[:positive] else value = -value if opt[:negative] && opt[:negative] != opt[:positive] opt[:negative] || opt[:positive] end end value = self.format_fixed_point( value, pattern, opt) value = opt[:unit]+value if opt[:unit] value.gsub!(/\./,opt[:separator]) if opt[:separator] if opt[:delimiter] && (m = value.match(/^(\D*)(\d+)(.*)/)) # Adapted From Rails' ActionView::Helpers::NumberHelper n = m[2].gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{opt[:delimiter]}") value=m[1]+n+m[3] end value end |
.integer_to_float(value, *args) ⇒ Object
Private: Converts the integer into a float value with the given fixed-point definition
value - integer to convert rules - hash of fixed-point conversion rules
Returns a float of the converted value
606 607 608 609 610 |
# File 'lib/easy_attributes.rb', line 606 def self.integer_to_float(value, *args) opt = args.last.is_a?(Hash) ? args.pop : {} return (opt[:blank]||nil) if value.nil? value = 1.0 * value / (10**(opt[:precision]||2)) end |