Skip to content

Commit

Permalink
Allow configuration of optional separator on output. (#149)
Browse files Browse the repository at this point in the history
  • Loading branch information
olbrich authored Dec 30, 2016
1 parent 6ecf4ea commit a04590c
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
Change Log for Ruby-units
=========================
2016-12-28 2.1.0 * add support for ruby 2.4.0
* allow configuration for optional separator on output
* Fix issue #105 -- change 'grad' to 'gon'
2015-11-07 2.0.0 * remove support for ruby versions less than 2.0
* remove `.unit` and `.u` from String
Expand Down
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,13 +259,29 @@ gem 'ruby-units', require: 'ruby_units/namespaced'

Note: when using the namespaced version, the Unit.new('unit string') helper will not be defined.

### Configuration

Configuration options can be set like:

```
RubyUnits.configure do |config|
config.separator = false
end
```

Currently there is only one configuration you can set:

1. separator (true/false): should a space be used to separate the scalar from the unit part during output.


### NOTES

#### Mathn

Note that the current implementation of ruby-units requires 'mathn' from the ruby standard library.
This tends to change the behavior of integer math in ways that many people do not expect, and can be the source
of numerous bugs and odd behaviors. If you encounter what appears to be a bug in your code that seems to be related

to the use of ruby-units, try to reproduce the bug by just including 'mathn' by itself.

If you identify a bug in a gem or code that uses mathn, please file a bug report or create a pull request to fix it.
Expand Down
41 changes: 41 additions & 0 deletions lib/ruby_units/configuration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# allow for optional configuration of RubyUnits
#
# Usage:
#
# RubyUnits.configure do |config|
# config.separator = false
# end
module RubyUnits
class << self
attr_writer :configuration
end

def self.configuration
@configuration ||= Configuration.new
end

def self.reset
@configuration = Configuration.new
end

def self.configure
yield configuration
end

# holds actual configuration values for RubyUnits
class Configuration
# used to separate the scalar from the unit when generating output.
# set to nil to prevent adding a space to the string representation of a unit
# separators other than ' ' and '' may work, but you may encounter problems
attr_reader :separator

def initialize
self.separator = true
end

def separator=(value)
raise ArgumentError, "configuration 'separator' may only be true or false" unless value.class == TrueClass || value.class == FalseClass
@separator = value ? ' ' : nil
end
end
end
1 change: 1 addition & 0 deletions lib/ruby_units/namespaced.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

# require_relative this file to avoid creating an class alias from Unit to RubyUnits::Unit
require_relative 'version'
require_relative 'configuration'
require_relative 'definition'
require_relative 'cache'
require_relative 'array'
Expand Down
11 changes: 6 additions & 5 deletions lib/ruby_units/unit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -644,16 +644,17 @@ def to_base
def to_s(target_units = nil)
out = @output[target_units]
return out if out
separator = RubyUnits.configuration.separator
case target_units
when :ft
inches = convert_to('in').scalar.to_int
out = "#{(inches / 12).truncate}\'#{(inches % 12).round}\""
when :lbs
ounces = convert_to('oz').scalar.to_int
out = "#{(ounces / 16).truncate} lbs, #{(ounces % 16).round} oz"
out = "#{(ounces / 16).truncate}#{separator}lbs, #{(ounces % 16).round}#{separator}oz"
when :stone
pounds = convert_to('lbs').scalar.to_int
out = "#{(pounds / 14).truncate} stone, #{(pounds % 14).round} lb"
out = "#{(pounds / 14).truncate}#{separator}stone, #{(pounds % 14).round}#{separator}lb"
when String
out = case target_units.strip
when /\A\s*\Z/ # whitespace only
Expand All @@ -663,7 +664,7 @@ def to_s(target_units = nil)
if $2 # unit specified, need to convert
convert_to($2).to_s($1)
else
"#{$1 % @scalar} #{$2 || units}".strip
"#{$1 % @scalar}#{separator}#{$2 || units}".strip
end
rescue # parse it like a strftime format string
(DateTime.new(0) + self).strftime(target_units)
Expand All @@ -676,9 +677,9 @@ def to_s(target_units = nil)
else
out = case @scalar
when Rational, Complex
"#{@scalar} #{units}"
"#{@scalar}#{separator}#{units}"
else
"#{'%g' % @scalar} #{units}"
"#{'%g' % @scalar}#{separator}#{units}"
end.strip
end
@output[target_units] = out
Expand Down
28 changes: 28 additions & 0 deletions spec/ruby_units/configuration_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
require 'spec_helper'

describe RubyUnits::Configuration do
context '.separator is true' do
it 'has a space between the scalar and the unit' do
expect(RubyUnits::Unit.new('1 m').to_s).to eq '1 m'
end
end

context '.separator is false' do
around(:each) do |example|
RubyUnits.configure do |config|
config.separator = false
end
example.run
RubyUnits.reset
end

it 'does not have a space between the scalar and the unit' do
expect(RubyUnits::Unit.new('1 m').to_s).to eq '1m'
expect(RubyUnits::Unit.new('14.5 lbs').to_s(:lbs)).to eq '14lbs, 8oz'
expect(RubyUnits::Unit.new('220 lbs').to_s(:stone)).to eq '15stone, 10lb'
expect(RubyUnits::Unit.new('14.2 ft').to_s(:ft)).to eq %(14'2")
expect(RubyUnits::Unit.new('1/2 cup').to_s).to eq '1/2cu'
expect(RubyUnits::Unit.new('123.55 lbs').to_s('%0.2f')).to eq '123.55lbs'
end
end
end

0 comments on commit a04590c

Please sign in to comment.