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

Measure: time math #12

Open
zverok opened this issue Jan 3, 2016 · 6 comments
Open

Measure: time math #12

zverok opened this issue Jan 3, 2016 · 6 comments

Comments

@zverok
Copy link
Contributor

zverok commented Jan 3, 2016

Seems to be implemented in multiple other libraries, so just use them/import code:

Measure(1, 'h').since # => Time.now + 1 hour
Measure(1, 'h').ago   # => Time.now - 1 hour

...and so on.

@ptolemybarnes
Copy link

Hey @zverok, really cool gem you have here. I'm interested in getting involved. A question on this: why not use an existing gem to handle units rather than roll your own? At a glance, this one might do.

@zverok
Copy link
Contributor Author

zverok commented Mar 5, 2016

Hey @ptolemybarnes!
It's REALLY complicated question, faithfully.

For one, current Reality state is compact yet useful prototype. I'd be really happy to use any other library instead of building my owns... But it happens so that existing libraries (of course, I evaluated ruby-units, as well as unitwise, ruby-measurement and several others) are powerful in some areas while helpless in others, that I feel as important.

For example, most of existing libraries are hard at extending their units system, while I (currently) think it is necessary:

require 'reality'
Reality::Entity('Ukraine').population
# => #<Reality::Measure(42,800,501 person)> 

require 'ruby-units'
Unit.new(42_800_501, 'person')
# => ArgumentError: '42800501 person' Unit not recognized

I REALLY want to use something external, and still thinking hard about it. If somebody (wink-wink) will do this carefully, I'd be happy!

My targets for Ideal Eternal Reality::Measure (either constructed independently, or used from external library, or being wrapper on several libraries):

  • no extension of core classes
  • pretty-looking and informative inspect (currently, I think our measure inspect looks more consistent than ruby-unit's one and more concise than unitwise's one, but my mind can be changed with good arguments)
  • math works (1m + 2m, 1km / 1h and so on)
  • conversions works (both implicitly, like 1km + 100m and explicitly, like 1km.to(m))
  • there are helpful synonyms, like 1km vs 1kilometer
  • appropriate fallback to native types:
# ruby-units: nope
(Unit.new(1, 'm') / Unit.new(2, 'm')).class
# => RubyUnits::Unit 

# unitwise: nope
(Unitwise(1, 'm') / Unitwise(2, 'm')).class
# => Unitwise::Measurement

# reality: yep
(Reality::Measure(1, 'm') / Reality::Measure(2, 'm')).class
# => Rational 
  • domain-specific processing; I'm absolutely not sure it should go to "core class", but somehow feel so. Like this tickete, where we are talking: neither ruby-units, nor unitwise can provide extended functionality for "time measurement" units... and I've event not speeking about currencies :) Which are also (from Reality's point of view) somewhere near this topic!

@zverok
Copy link
Contributor Author

zverok commented Mar 5, 2016

neither ruby-units, nor unitwise can provide extended functionality for "time measurement" units...

ok, looking closer at it, ruby-units seems to can... though, by extending core classes. which is pretty questionable practice for widely-used gems (unless this gem is rails/active_support, but it's not the case)

@zverok
Copy link
Contributor Author

zverok commented Mar 5, 2016

require 'ruby-unit'
Unit.new(1000, 'm') / Unit.new(1, 'm')
# => 1000 --- ok
Unit.new(1, 'km') + Unit.new(1, 'm')
# => 1.001 km --- ok
Unit.new(1, 'km') / Unit.new(1, 'm')
# => 1 km/m --- NOT OK

...and so on, and so on.

@ptolemybarnes
Copy link

I see. I can't see how you can have complete extensibility and be able to convert between measurements in like units though. For example, if we want to do:

Measure.new(1, 'km') + Measure.new(1, 'm')

Then the units 'km' and 'm' have to somehow know about each other so that they can know that they're compatible. But the way units are being created at the moment doesn't allow for that. Please correct me on this if I'm wrong; I haven't spent that much time exploring the code yet. :)

@zverok
Copy link
Contributor Author

zverok commented Mar 6, 2016

Yes, currently Measure is kind of "early draft" (as almost everything inside). I haven't made up my mind yet of how to provide convertability, there are three major options, as I can see:

  • just have some dictionary (hash) of unit correspondences, and examine it on the fly;
  • make some serious Unit Definition API (like Unitwise and ruby-units do);
  • just use one of them (internally, or instead of Measure, with some custom additions: allow adding units on-the-fly; at least unitwise's author thinks it is principally possible).

Maybe even on-the-fly units is not what we want, but rather predefined list (which should be, though, larger than "just physical units").

So, I'm open to discussions and proposals!

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

No branches or pull requests

2 participants