Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Two questions: #to_hash and custom units #22

Open
zverok opened this issue Dec 16, 2015 · 2 comments
Open

Two questions: #to_hash and custom units #22

zverok opened this issue Dec 16, 2015 · 2 comments

Comments

@zverok
Copy link

zverok commented Dec 16, 2015

(Sorry, it's currently not an bug report/feature request, rather a questions. I am currently evaluating Unitwise for my tasks and haven't find another way to communicate.)

About #to_hash methods

As far as I know, Ruby has following convention:

  • object provides to_h if it can be somehow converted to hash;
  • object provides to_hash if it thinks of itself as a some kind of hash.

Unitwise's classes currently define to_hash method, while, I think, they can not be seen as "some kind of hash".

Theoretical example of bad consequences:

def test(**options)
  p options
end

test(1) # fails with ArgumentError, which is as expected
test(Unitwise(1, 'm')) # calls test with a large hash, which is strange

Practical examle of bad consequences: when using awesome_print gem in irb (which is pretty common), it outputs those large hashes instead of compact #inspect results.

About custom units

Unitwise provides very cool, effective, well-writen and well-tested code for working with units. What could make me (and, maybe, not only me?) happy is possibility, optional, to work with any units outside the controlled dictionary. Supposed synopsys:

# Variant 1:
Unitwise(1000, 'person') # => fails
require 'unitwise/custom_units'
Unitwise(1000, 'person') # => ok

# Variant 2:
Unitwise(1000, 'person') # => fails
Unitwise::Unit.define 'person' # + some options
Unitwise(1000, 'person') # => ok

# ...and now:
Unitwise(1000, 'person') / Unitwise(1, 'km') # => Unitwise(1000 'person/km')
Unitwise(10, 'person')**2 # => Unitwise(100, 'person2')

WDYT?

@joshwlewis
Copy link
Owner

On the #to_hash part, I think you are correct. I'll update that in a future release.

On the person unit, that seems a little weird since it's just a count of something. That's essentially what an Integer is for. Also, UCUM defined a 1 unit code that's primarily intended for counts. I don't know your situation, but my naive stance would be to use one of those.

However, you piqued my interest with the custom units idea. I poked around a bit in irb, and I was able to get a custom unit loaded:

person_data = {:names=>"Person", :symbol=>"person", :primary_code=>"person", :scale=>{:value=>1.0, :unit_code=>"1"}, classification: "dimless"}

person = Unitwise::Atom.new(person_data)

Unitwise::Atom.all << person

Unitwise(10, "person")**2
=> #<Unitwise::Measurement value=100 unit=Pers2>

A few caveats here:

  • Parsing results are memoized, so you'll need to load the Atom before you start using Unitwise elsewhere. Loading the atom in should probably happen in an initializer or something similar.
  • There might be a set of properties that make more sense for you. Take a look here to figure out atom initialization options.
  • The fact that this works is somewhat unintentional, and certainly untested. It might behave strangely.

@zverok
Copy link
Author

zverok commented Jan 18, 2016

On the person unit, that seems a little weird since it's just a count of something. That's essentially what an Integer is for. Also, UCUM defined a 1 unit code that's primarily intended for counts. I don't know your situation, but my naive stance would be to use one of those.

The situation is here: https://github.com/molybdenum-99/reality
I'm currently using custom (pretty naive) implementation of units (Reality::Measure):

ar = Reality.country('Argentina')
# => #<Reality::Country(Argentina)> 
ar.population
# => #<Reality::Measure(43,417,000 person)> 
ar.area
# => #<Reality::Measure(2,780,400 km²)> 
ar.population + ar.area
# ArgumentError: 43,417,000person incompatible with 2,780,400km²
ar.population / ar.area
# => #<Reality::Measure(15 person/km²)> 

In other words, I need for that project "controlled units" and "pretty output" much more than "smart conversions". And I'm curious if Unitwise is a right tool for the task.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants