olbrich / ruby-units Goto Github PK
View Code? Open in Web Editor NEWA unit handling library for ruby
License: MIT License
A unit handling library for ruby
License: MIT License
I'm looking for a method that scales the SI units to the most appropriate scaling prefix. E.g., if I have "4096 KiB", I see no direct method or trick that will format this to "4.0 MiB", though after perusing the source, I do see I can get there (if I already know the scale I want) by doing "4096 KiB".unit().to_s("MiB"), or ".0000032 cm".unit().to_s("nm").
But I'd like to do it without knowing the "best" scale; I often have to print values that might be 2 B, or 2 PiB, or anywhere in between. By best, I think I mean the fewest prefixes, where the prefix(es) chosen leave the scalar at a value between 1 and the next larger scaling prefix. I suspect the conversion needs to be able to say which scaling vector to use (e.g., the 2**(10x) vector vs. the 10**(3x) vector); wouldn't want to get in a fight between a RAM vendor and a disk vendor about what GB means.
I don't see anything in the referenced IEEE Xplore article about handling this part of the problem; I can see it might be a tad challenging when dealing with something like 4.2e-6 centigram nanoparsecs / kilosecond .
Ruby-units overrides the Time class's at() method with a new on that only accepts one argument.
The standard time class accepts an optional second microseconds method
http://ruby-doc.org/core-1.9.3/Time.html
I think it would be enough to add a second optional milliseconds argument to your at() method and pass it through to the unit_time_at call in the else{} block, but I'm not totally sure.
def self.at(arg, ms = 0)
case arg
when Unit
unit_time_at(arg.convert_to("s").scalar)
else
unit_time_at(arg, ms)
end
end
It appears that when a unit has multiple prefixes, all but the last one are ignored. That is to say, the following all equal 3 cg
:
Unit.new('3 mcg') # this is how I originally discovered the issue,
# mistakenly thinking this would be micrograms
Unit.new('3 ccg')
Unit.new('3 cccccg')
Unit.new('3 yottagigamicrocg')
I don't know what should happen (is a ccg a hundredth of a hundredth of a gram, or just meaningless garbage?), but I presume silently throwing away input is not the desired behavior.
rcov seems to only work on 1.8.7, try using simplecov or something ssimilar in 1.9.2
1 F = 1 m^2_kg^-1_s^4*A^2
irb(main):017:0> q = "1003 kg*m".to_unit
=> 1003 kg*m
irb(main):019:0> (q / 100.0).ceil
ArgumentError: '11 <kilogram><meter>/<1>' Unit not recognized
I've just noticed a (really) strange bug. Try the following code in irb:
irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'ruby-units'
=> true
irb(main):003:0> # add three volumes using ruby-units
irb(main):004:0* s = '2ml'.to_unit + '3ml'.to_unit + '1ml'.to_unit
=> 6 ml
irb(main):005:0> s.units
=> "ml"
irb(main):006:0> s.scalar
=> 6.0
irb(main):007:0> # create a value to compare against
irb(main):008:0* r = '6ml'.to_unit
=> 6 ml
irb(main):009:0> r.units
=> "ml"
irb(main):010:0> r.scalar
=> 6.0
irb(main):011:0> # now compare them (they should be equal)
irb(main):012:0* s == r
=> false
irb(main):013:0> # huh??? yet if I do this it works
irb(main):014:0* '6ml'.to_unit == r
=> true
irb(main):015:0> # try subtraction instead
irb(main):016:0* m = '10ml'.to_unit - '3ml'.to_unit - '1ml'.to_unit
=> 6 ml
irb(main):017:0> m == r
=> false
irb(main):018:0> # again, huh??? yet if I do this it works
irb(main):019:0* '6ml'.to_unit == r
=> true
What I'm doing is summing a few volumes using ruby units. If I add them then, even though the sum is a unit and is the correct amount, if I compare the result then comparison fails. The same happens for subtraction.
However, what's odd is that if I do both addition and subtraction in the same expression, it works
irb(main):020:0> # now the weird bit: if I do both addition and subtraction, it works
irb(main):021:0* a = '2ml'.to_unit + '5ml'.to_unit - '1ml'.to_unit
=> 6 ml
irb(main):022:0> a == r
=> true
Multiplication doesn't seem to have this problem:
irb(main):023:0> x = '2ml'.to_unit * 3
=> 6 ml
irb(main):024:0> x == r
=> true
A temporary workaround is to convert back to a string and then to a unit again, but it would be easy to forget (and is quite wasteful)
irb(main):025:0> s = ('2ml'.to_unit + '3ml'.to_unit + '1ml'.to_unit).to_s.to_unit
=> 6 ml
irb(main):026:0> s == r
=> true
Currently I am trying to multiply an ore by its mineral grade to get the contained mineral
irb(main):001:0> ore='189 Mtonne'.u
=> 189 Mtonne
irb(main):002:0> grade='1189 g/tonne'.u
=> 1189 g/tonne
irb(main):003:0> mineral=ore_grade
=> 224721 g_Mtonne/tonne
irb(main):004:0> mineral.to('tonne')
=> 224.721 tonne
The correct answer is in fact '224721 tonne', which makes the out by a factor of one thousand. I seem to have pinned down where in the code this error occurs, lines 793-801 in Unit.rb, and after commenting it out, I get the right figures.
Essentially, the term 1000 is found in _numerator1, _denominator1 and _numerator2, but is only eliminated from _numerator1 in the second block of those lines.
I'm running into an issue where my project already has an ActiveRecord class named Unit
. I would like to use the ruby-unit
gem, but unfortunately I can't since your class is named Unit
as well. It would be nice if it was something unique like Measurement::Unit
, Olbrich::Unit
, or similar.
....or a Google group? I have a question and would like to ask it in the correct forum.
In the case there is no other place: I want to define some specialized unit types but am stumbling a little.
specific_gravity.definition = Unit(1)
?Please direct me to the right place to ask such questions. Thanks.
Anything in the work? Will create pull request if no work has started on this
FYI for anyone interested, I just released a validation gem for rails 3.2 that can use ruby-units to validate a model column. https://github.com/dgm/unit_validation
Improve formatting of generated documentation so that YARD-style docs are more useful and more accurate
Overriding the "/" method causes problems in the in_groups array method in ActiveSupport, Rails, version 2.3.2
e.g.
[1,2,3,4,5,6].in_groups(4, false)
=> [[1, 2], [3, 4], [6], []] # Note that the 5 is missing
and
[1,2,3,4,5,6,7].in_groups(4, false)
NoMethodError: undefined method `concat' for nil:NilClass
the in_groups method uses the slice array method and it does not accept fractions.
I note the definition of a fluid-ounce
is the only volume lacking a plural.
Unit.define('fluid-ounce') do |floz|
floz.definition = Unit('1/128 gal')
floz.aliases = %w{floz fluid-ounce}
end
ought to include
floz.aliases = %w{floz fluid-ounce fluid-ounces}
It would be very handy if you could add this simple change.
Thanks
Dave
At the moment, counting units appear to be treated as interchangeable.
Unit.new('3 dB') == Unit.new('3 sr') # => true
Unit.new('3 sr') == Unit.new('3 nt') # => true
Unit.new('3 nt') == Unit.new('3 bp') # => true
Unit.new('3 bp') == Unit.new('3 molecule') # => true
Unit.new('3 molecule') == Unit.new('3 each') # => true
Unit.new('3 each') == Unit.new('3') # => true
As shown below - first time using a unit rationals are maintained properly, however in subsequent uses of that unit rational values are converted to decimals
u=Unit.new('1/4 mm')
=> 1/4 mm
v=Unit.new('1/4 mm')
=> 0.25 mm
u=Unit.new('1/4 in')
=> 1/4 in
v=Unit.new('1/4 mm')
=> 0.25 mm.
Hi
This is not an issue so I apologise, but I'm not sure how else to contact you.
I'm using ruby-units 1.1.5 in my app and I'd like to upgrade to the latest ruby-units. If I do this will it just work or has the api changed so that it won't?
Cheers
Chris
Is it possible to request a specific description of a unit when converting to a string?
For example, currently:
Unit('1 cup').to_s #=> 1 cu
Is it possible to say:
Unit('1 cup').to_s('cup') #=> 1 cup
I do realize that passing a measurement type to to_s will convert to the specified unit before converting to a string.
If this isn't implemented, I could consider some options and submit a pull request.
1.9.3-p194 :001 > 1/2
=> 0
1.9.3-p194 :002 > require 'ruby-units'
=> true
1.9.3-p194 :003 > 1/2
=> (1/2)
1.9.3-p194 :004 > 1/2.0
=> (1/2)
I didn't install any other gem, and I read ruby-units code a little bit and found nothing. Could someone tell me what happening here because I don't want to change a lot of code in my repository.
Thanks
Without the ruby-units gem I get:
ruby-1.9.2-p180 > ans = 2/3
=> 0
ruby-1.9.2-p180 > ans.class
=> Fixnum
With the ruby-units gem I get:
ruby-1.9.2-p180 > ans = 2/3
=> (2/3)
ruby-1.9.2-p180 > ans.class
=> Rational
I'm not sure if this is expected behaviour or not, but several other gems I use expect the former behaviour (e.g. in while loop conditions) and so break when used together with the ruby-units gem.
If this is a necessary consequence of the way the gem works then you might want to put a brief warning in the readme. If not, it'd be great if the gem could leave standard ruby behaviour intact and still work its unit-based magic.
Cheers,
Jon
I have had no problems with this gem in development, but it continues to cause issues in production. It either fails silently or gives me an uninitialized constant error with my rails app. I've gotten it to work on dev and production on my mac and vagrant but it continues to fail in production on my linode. Do you have any insight?
ActionView::Template::Error (uninitialized constant Unit):
55:
56: <% slis.each do |sli| %>
57:
58: <%= display_sli(sli) %>
59: <%= match_recipe_index(sli, @sl) %>
60: <%= link_to content_tag(:i, "", class: (mode == :unpurchased ? "icon-remove" : "icon-plus-sign") ),
61: toggle_purchased_shopping_list_ingredient_path(sli), method: :post %>
app/models/shopping_list_ingredient.rb:27:in convert_ingredient' app/helpers/shopping_lists_helper.rb:13:in
display_sli'
I have tried to add 'require ruby-units' to the top of my model's but i get this error:
/home/deployer/apps/saute/shared/bundle/ruby/1.9.1/gems/activesupport-3.2.1/lib/active_support/dependencies.rb:317:in `rescue in depend_on': No such file to load -- ruby-units (LoadError)
Fresh Rails 3.2.11 app with pry-rails 0.2.2. ruby-units keeps echoing garbage...
$ b rails c
Loading development environment (Rails 3.2.11)
[1] pry(main)> []
=> []ry(main)> []/120B
[2] pry(main)> puts "hello world"
hello worldn)> puts "hello world"/40B
=> nil
[3] pry(main)> exit
[3] pry(main)> exit/120B
$
Thanks for the help.
I think it would be more consistent if strings containing only whitespace (e.g. " ".to_unit) raised an error like "".to_unit
ruby-1.8.7-p160 > " ".to_unit
=> 1
ruby-1.8.7-p160 > "".to_unit
ArgumentError: No Unit Specified
For example:
1.9.3p194 :034 > Unit.defined?("foot")
=> true
1.9.3p194 :035 > Unit.defined?("ft")
=> false
1.9.3p194 :036 > Unit.defined?("pound")
=> true
1.9.3p194 :037 > Unit.defined?("lb")
=> false
/Users/clintbounds/.rvm/gems/ruby-1.8.7-p330@plantoeat/gems/ruby-units-1.3.1/lib/ruby_units/unit.rb:1228:in 'parse'
/Users/clintbounds/.rvm/gems/ruby-1.8.7-p330@plantoeat/gems/ruby-units-1.3.1/lib/ruby_units/unit.rb:243:in 'initialize'
/Users/clintbounds/.rvm/gems/ruby-1.8.7-p330@plantoeat/gems/ruby-units-1.3.1/lib/ruby_units/string.rb:5:in 'new'
/Users/clintbounds/.rvm/gems/ruby-1.8.7-p330@plantoeat/gems/ruby-units-1.3.1/lib/ruby_units/string.rb:5:in 'unit'
/Users/clintbounds/.rvm/gems/ruby-1.8.7-p330@plantoeat/gems/ruby-units-1.3.1/lib/ruby_units/string.rb:34:in 'from'
generated code (/Users/clintbounds/.rvm/gems/ruby-1.8.7-p330@plantoeat/gems/actionpack-2.3.9/lib/action_controller/routing/route.rb:205):14:in 'recognize'
(recognize_optimized):8:in 'recognize_optimized'
Pretty sure that 3.01 V is 3010 mV. So when I try to convert, why am I getting this?
u = Unit.new("3.01 V") >> "mV"
puts u.scalar # 3009.9999999999995
I also get this issue when upconverting as well.
u = Unit.new("3.01 mV") >> "V"
puts u.scalar # 0.0030099999997
Yet this seems to work properly for
u = Unit.new("3.02 V") >> "mV"
puts u.scalar # 3020.0
Can anyone clarify if this is an issue or feature. Thanks, much appreciated
This gem should work with ruby 1.9.x
There are some of these still lurking around, convert them to rspec and remove them.
I am using the ruby-units 1.2.0.a since I was having problems with the 1.1.5 the date.rb which is a separate issue.
/Users/WadBook/.rvm/gems/ruby-1.9.2-p0/gems/ruby-units-1.1.5/lib/ruby_units/date.rb:16: warning: else without rescue is useless
/Users/WadBook/.rvm/gems/ruby-1.9.2-p0/gems/ruby-units-1.1.5/lib/ruby_units/date.rb:29: warning: else without rescue is useless
/Users/WadBook/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:239:in `require': /Users/WadBook/.rvm/gems/ruby-1.9.2-p0/gems/ruby-units-1.1.5/lib/ruby_units/date.rb:10: syntax error, unexpected ':', expecting keyword_then or ',' or ';' or '\n' (SyntaxError)
/Users/WadBook/.rvm/gems/ruby-1.9.2-p0/gems/ruby-units-1.1.5/lib/ruby_units/date.rb:13: syntax error, unexpected keyword_when, expecting keyword_end
when Time: unit_date_add(unit.to_datetime)
^
/Users/WadBook/.rvm/gems/ruby-1.9.2-p0/gems/ruby-units-1.1.5/lib/ruby_units/date.rb:23: syntax error, unexpected ':', expecting keyword_then or ',' or ';' or '\n'
when Unit:
^
/Users/WadBook/.rvm/gems/ruby-1.9.2-p0/gems/ruby-units-1.1.5/lib/ruby_units/date.rb:26: syntax error, unexpected keyword_when, expecting keyword_end
when Time: unit_date_sub(unit.to_datetime)
^
/Users/WadBook/.rvm/gems/ruby-1.9.2-p0/gems/ruby-units-1.1.5/lib/ruby_units/date.rb:30: syntax error, unexpected keyword_end, expecting $end
I used the 1.2.0.a version of the gem and it solved the problem above but none of my routing works now.
in my routing tests for the index action of my controller I get:
Unknown target units
and for my other actions I get
Unit not recognized
This clearly seems to be a conflict between ruby-units and Rails.
Perhaps adding a namespace could help
Using rails 3.0.3 and ruby 1.9.2-p0
I'm trying to move an application from Ruby 192 and Rails 3.0 to Ruby 193 and Rails 3.2. I'm hitting an error doing simple math between Units where one scalar value is BigDecimal and the other is a Rational. The following works on Ruby 192:
/Users/rickeaton/.rvm/rubies/ruby-1.9.3-p194/bin/ruby -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) /Users/rickeaton/railsprojects/myssp/script/rails console
Loading development environment (Rails 3.2.8)
Switch to inspect mode.
a = Unit.new(3/2, "lbs")
3/2 lbsb = Unit.new(BigDecimal.new(1.5,4), "lbs")
1.5 lbsa+b
'
TypeError: Rational can't be coerced into BigDecimal
from /Users/rickeaton/.rvm/gems/ruby-1.9.3-p194@rails328/gems/ruby-units-1.4.1/lib/ruby_units/unit.rb:713:in*' from /Users/rickeaton/.rvm/gems/ruby-1.9.3-p194@rails328/gems/ruby-units-1.4.1/lib/ruby_units/unit.rb:713:in
+'
from (irb):5
from /Users/rickeaton/.rvm/gems/ruby-1.9.3-p194@rails328/gems/railties-3.2.8/lib/rails/commands/console.rb:47:instart' from /Users/rickeaton/.rvm/gems/ruby-1.9.3-p194@rails328/gems/railties-3.2.8/lib/rails/commands/console.rb:8:in
start'
from /Users/rickeaton/.rvm/gems/ruby-1.9.3-p194@rails328/gems/railties-3.2.8/lib/rails/commands.rb:41:in<top (required)>' from /Users/rickeaton/railsprojects/myssp/script/rails:6:in
require'
from /Users/rickeaton/railsprojects/myssp/script/rails:6:in<top (required)>' from -e:1:in
load'
from -e:1:in `
Any ideas how or if this can be fixed or can you suggest a workaround? This gem has been very useful for me!
When using the ruby-units 1.3.1 gem and trying to use the YAML::load in the rails console I got an error message with the following information:
ArgumentError: wrong number of arguments (2 for 1)
from /Users/herminio/.rvm/gems/ruby-1.9.2-p290/gems/ruby-units-1.3.1/lib/ruby_units/time.rb:14:in at' from /Users/herminio/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych/scalar_scanner.rb:91:in
parse_time'
from /Users/herminio/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych/scalar_scanner.rb:42:in tokenize' from /Users/herminio/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych/visitors/to_ruby.rb:46:in
visit_Psych_Nodes_Scalar'
from /Users/herminio/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych/visitors/visitor.rb:6:in accept' from /Users/herminio/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych/visitors/to_ruby.rb:16:in
accept'
from /Users/herminio/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych/visitors/to_ruby.rb:205:in block in visit_Psych_Nodes_Mapping' from /Users/herminio/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych/visitors/to_ruby.rb:190:in
each'
from /Users/herminio/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych/visitors/to_ruby.rb:190:in each_slice' from /Users/herminio/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych/visitors/to_ruby.rb:190:in
visit_Psych_Nodes_Mapping'
from /Users/herminio/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych/visitors/visitor.rb:7:in accept' from /Users/herminio/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych/visitors/to_ruby.rb:16:in
accept'
from /Users/herminio/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych/nodes/node.rb:25:in to_ruby' from /Users/herminio/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych.rb:107:in
load'
from (irb):14
During testing there is this warning:
/lib/ruby_units/ruby-units.rb:368: warning: 2 digits year is used
Which results from this assertion in test_time:
assert_equal "01:00", "min".since(Time.now - 3600).to_s("%H:%M")
The actual cause is the use of Time.gm(0) in Unit.to_s
# [ruby_units/ruby-units.rb]
...
rescue #if that is malformed, try a time string
out = (Time.gm(0) + self).strftime(target_units)
end
I was wondering if this should be Time.at(0)? Time.gm(0) is interpreted as Time.gm(2000), so whatever self is will be with respect to 'Sat Jan 01 00:00:00 UTC 2000' rather than epoch.
Time.gm(0) # => Sat Jan 01 00:00:00 UTC 2000
Time.gm(2000) # => Sat Jan 01 00:00:00 UTC 2000
Time.at(0) # => Wed Dec 31 17:00:00 -0700 1969
a = 1.to_unit
a.class #=> Unit
(1-a).class #=> Unit
(a-a).class #=> Float
These should be consistent
The negation operator returns just the negation of the scalar when the unit is unitless.
We're seeing inconsistent behaviour with Unit(...)
when passing in invalid units:
ree-1.8.7-2011.03 :010 > Unit("1 foos/second").base
ArgumentError: '1 foos/second' Unit not recognized
from .../.bundle/ruby/1.8/gems/ruby-units-1.4.0/lib/ruby_units/unit.rb:1463:in `parse'
from .../.bundle/ruby/1.8/gems/ruby-units-1.4.0/lib/ruby_units/unit.rb:363:in `initialize'
from .../.bundle/ruby/1.8/gems/ruby-units-1.4.0/lib/ruby_units/unit.rb:347:in `initialize'
from .../.bundle/ruby/1.8/gems/ruby-units-1.4.0/lib/ruby_units/array.rb:7:in `new'
from .../.bundle/ruby/1.8/gems/ruby-units-1.4.0/lib/ruby_units/array.rb:7:in `to_unit'
from .../.bundle/ruby/1.8/gems/ruby-units-1.4.0/lib/ruby_units/object.rb:9:in `Unit'
from (irb):10
ree-1.8.7-2011.03 :011 > Unit("1 second/foo").base
=> 1 s
It would make more sense for Unit("1 second/foo").base
to also throw an ArgumentError
.
I'm trying to move a simple project forward from 1.8.7 but run into a problem using the t/translate helper in my views. I tried to make this replicable in irb, but don't know all the correct dependencies to require so I've just done it on the console.
Making a simple project with Rails 3.0.9 and the latest ruby-units gem, here's the difference in 1.8.7 vs. 1.9.2:
1.8.7
include ActionView::Helpers::TagHelper
include ActionView::Helpers::TranslationHelper
translate(:chris)
=> "<span class="translation_missing" title="translation missing: en.chris">Chris"
1.9.2
include ActionView::Helpers::TagHelper
include ActionView::Helpers::TranslationHelper
translate(:chris)
ArgumentError: 'chris' Unit not recognized
from /Users/cwise/.rvm/gems/ruby-1.9.2-p180/gems/ruby-units-1.3.1/lib/ruby_units/unit.rb:1228:in parse' from /Users/cwise/.rvm/gems/ruby-1.9.2-p180/gems/ruby-units-1.3.1/lib/ruby_units/unit.rb:243:in
initialize'
from /Users/cwise/.rvm/gems/ruby-1.9.2-p180/gems/ruby-units-1.3.1/lib/ruby_units/string.rb:5:in new' from /Users/cwise/.rvm/gems/ruby-1.9.2-p180/gems/ruby-units-1.3.1/lib/ruby_units/string.rb:5:in
to_unit'
from /Users/cwise/.rvm/gems/ruby-1.9.2-p180/gems/ruby-units-1.3.1/lib/ruby_units/string.rb:65:in to' from /Users/cwise/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.0.9/lib/active_support/core_ext/string/access.rb:85:in
first'
from /Users/cwise/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.9/lib/action_view/helpers/translation_helper.rb:65:in scope_key_by_partial' from /Users/cwise/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.9/lib/action_view/helpers/translation_helper.rb:48:in
translate'
from (irb):3
from /Users/cwise/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.9/lib/rails/commands/console.rb:44:in start' from /Users/cwise/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.9/lib/rails/commands/console.rb:8:in
start'
from /Users/cwise/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.9/lib/rails/commands.rb:23:in <top (required)>' from script/rails:6:in
require'
from script/rails:6:in `
Using latest ruby-units and will_paginate (with rails) an exception is always thrown when trying to render the pagination.
ActionView::Template::Error in MailingsController#index
'previous_label' Unit not recognized
Backtrace
ruby-units (1.3.1) lib/ruby_units/unit.rb:1228:in `parse'
ruby-units (1.3.1) lib/ruby_units/unit.rb:243:in `initialize'
ruby-units (1.3.1) lib/ruby_units/string.rb:5:in `new'
ruby-units (1.3.1) lib/ruby_units/string.rb:5:in `to_unit'
ruby-units (1.3.1) lib/ruby_units/string.rb:65:in `to'
activesupport (3.1.1.rc2) lib/active_support/core_ext/string/access.rb:85:in `first'
actionpack (3.1.1.rc2) lib/action_view/helpers/translation_helper.rb:65:in `scope_key_by_partial'
actionpack (3.1.1.rc2) lib/action_view/helpers/translation_helper.rb:48:in `translate'
will_paginate (3.0.2) lib/will_paginate/view_helpers/action_view.rb:83:in `will_paginate_translate'
will_paginate (3.0.2) lib/will_paginate/view_helpers.rb:78:in `will_paginate'
will_paginate (3.0.2) lib/will_paginate/view_helpers/action_view.rb:33:in `will_paginate'
....
The internal unit cache is there to improve performance, but the implementation of it is less than fantastic.
$ sudo gem list ruby-units
*** LOCAL GEMS ***
ruby-units (1.4.1)
$ irb --version
irb 0.9.5(05/04/13)
$ ruby --version
ruby 1.8.7 (2010-01-10 patchlevel 249) [universal-darwin10.0]
$ irb
irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'ruby-units'
=> true
irb(main):003:0> a = Unit.new('3 cm^3')
=> 3 cm^3
irb(main):004:0> b = Unit.new(a)
=> 3 cm^3
irb(main):005:0> b - Unit.new('1.5 cm^3')
ArgumentError: Incompatible Units ('3 cm^3' not compatible with '1.5 cm^3')
from /Library/Ruby/Gems/1.8/gems/ruby-units-1.4.1/lib/ruby_units/unit.rb:751:in `-'
from (irb):5
from :0
irb(main):006:0>
In the unit_definitions / standard.rb file 'pt' is used as an alias twice.
Unit.define('pint') do |pint|
pint.definition = Unit('1/8 gal')
pint.aliases = %w{pt pint pints}
end
Unit.define('point') do |point|
point.definition = Unit('1/72 ft')
point.aliases = %w{pt point points}
end
I believe the pint is created first and the point unit overrides it's 'pt' alias in the base_unit_cache. In my project I was using pints as pt, and now that is broken. I have fixed it with an initializer in my project, but I feel like one of these should be removed.
I could submit a trivial pull request fixing it one way or another, but as the gem author it is probably your call on which one to keep.
ruby-1.9.2-p180-patched :039 > "96 in".unit.to('ft')
=> 8 ft
but
ruby-1.9.2-p180-patched :042 > "96 in".unit.to_s(:ft)
=> "7'11""
Rework the way units are defined internally so that it's simpler to define or redefine units.
Example:
Unit.define!("jiffy") do |unit|
unit.definition = Unit("1/100 seconds")
end
ruby-1.8.7@ruby-units
ruby-1.8.7@ruby-units-with-chronic
ruby-1.9.2-head@ruby-units
ruby-1.9.2-head@ruby-units-with-chronic
rbx-head@ruby-units
Not sure if this is a known issue or not but ruby-units with Ruby 1.9.2-p0's idea of 1 second in nanoseconds is not quite the same as Ruby 1.8.7. For example:
ruby-1.9.2-p0 > "1 second".to("nanoseconds").scalar
=> 999999999.9999999
Whereas in ruby 1.8.7, the same set of actions yields 1 billion:
irb(main):007:0> "1 second".to("nanoseconds").scalar
=> 1000000000.0
Interestingly enough, in Ruby 1.9.2, plural seconds > 2 convert properly:
ruby-1.9.2-p0 > "2 seconds".to("nanoseconds").scalar
=> 1999999999.9999998
ruby-1.9.2-p0 > "3 seconds".to("nanoseconds").scalar
=> 3000000000.0
The order that ruby-units classes are currently loaded (specified in lib/ruby_units.rb) loads lib/ruby_units/units.rb and lib/ruby_units/ruby_units.rb last, however, every other file in ruby-units requires use of the Unit class (defined in ruby_units.rb). In effect they refer to the Unit class before it's defined.
This doesn't seem to be a problem using MRI ruby (which I presume evaluates when the methods are called) but this causes Rubinius to crash when ruby-units is required.
This was originally raised as a bug in Rubinius itself (here) but they pointed me towards ruby-units itself.
Also, as an aside, I'd suggest changing lib/ruby_units.rb and lib/ruby-units.rb so that one just requires the other rather than duplicating the requires in both (this is what rails does - eg. here and here)
$ be irb
rree-1.8.7-2011.03 :001 > require 'ruby-units'
=> true
ree-1.8.7-2011.03 :002 > Unit.new( nil, "ton/hectare" )
=> 1 ton/hectare
We do not expect nil
to become 1
:)
This bug happens because internally the arguments are converted to " ton/hectare"
, which parse()
somehow extracts a scalar out of.
We'd expect either an ArgumentError
to be thrown in this case, or for nil
to be represented by a special-case unit.
$ gem install ruby-units
Successfully installed ruby-units-1.1.5
1 gem installed
Installing ri documentation for ruby-units-1.1.5...
unrecognized option `--markup'
For help on options, try 'rdoc --help'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.