Often we have `Integer`’s but don’t have a clue what the unit is unless we encode it in a varible name. How can we prevent adding two numbers which are of different or incompatible units…

``````class IntegerWithUnit < SimpleDelegator

def initialize(integer, unit)
@unit = unit.to_sym.freeze
super(integer)
end

def unit?(unit)
@unit == unit.to_sym
end

def to_int
self
end

def to_s
super + " " + unit.to_s
end

def to_str
to_s
end

def inspect
to_s
end
end``````
``````num = IntegerWithUnit.new(1, :byte)
# => 1 byte

"Remaining: #{num}"
# => "Remaining: 1 byte"

num + 2
# => 3

(num + 2).class
# => Integer
# oops, we need to return an IntegerWithUnit

IntegerWithUnit.new(1, :byte) == IntegerWithUnit.new(1, :mile)
# => true
# oops, no it doesn't...``````
``````class Byte < IntegerWithUnit
def initialize(number)
super(number, :byte)
end
end``````

We can then allow certain types to be involved in arithmetic, e.g.

``````n1 = Byte.new(1)
n2 = Megabyte.new(2)

n1 + n2
# => 1000001 byte``````

Do we need to add pluralization, so:

``````Byte.new(2)
# => 2 bytes``````

This would need an inflection library, or it is an optional arguments, e.g.:

``IntegerWithUnit.new(2, [:byte, :bytes])``

``````FloatWithUnit.new(2.0, :miles)
# => 2.0 mile

IntegerWithUnit.new(2, :bytes).to_f
#=> 2.0 byte``````

And sugar:

``````Byte.new(2).to_megabyte
Mile.new(2).to_kilometers``````

Where do we store the conversion ratios between units?

In a chosen base unit, e.g. Byte has all conversions to Megabyte, Gigabyte etc. What about going from say kilometers to miles…

Maybe we have to convert to a base unit, do addition, and then back to the target unit. Each class has a conversion to the base unit, so `Byte::ToByte = 1`, `Kilobyte::ToByte = 1000` etc.

If this where to be gemified then we would want to wrap all class in a module instead of poluting the root namespace. In which case we could have:

``````module Unit
class Integer < SimpleDelegator

def initialize(integer, unit)
@unit = unit.to_sym.freeze
super(integer)
end

# ...
end

class Byte < Integer
end
end``````

But then does a `Unit::Byte` inherit from `Unit::Integer` or `Unit::Float`?

Would we need a base class, `ValueWithUnit`, which picks the correct class, `Integer` versus `Float`… Is it even needed since we are delegating to the passed in value…

``````IntegerWithUnit.new(1.2, :byte)
# => 1.2 byte

IntegerWithUnit.new({}, :byte)
# => {} byte``````

``````module Unit
class Object < SimpleDelegator

def initialize(obj, unit)
@unit = unit.to_sym.freeze
super(obj)
end

# ...
end

class Byte < Object
def initialize(number)
super(number, :byte)
end
end
end``````

There are so many different units they might need to be in seperate gems, e.g. bitcoin denominations.

From here it is proberbly best to write a README showing the desired API and then copy the examples to form the basis of the feature specs.