#!/usr/bin/ruby

#
## https://rosettacode.org/wiki/Define_a_primitive_data_type
#

class MyInt(Number value {|n| (n <= 10) && (n >= 1) && n.is_int } ) {

    method ==(arg)   { self.value == arg.value }
    method to_s      { value.to_s }

    method +(Number arg) { MyInt(value + arg.int) }
    method +(arg)        { self + arg.value }

    method /(Number arg) { MyInt(value / arg.int -> int) }
    method /(arg)        { self / arg.value }

    method -(Number arg) { MyInt(value - arg.int) }
    method -(arg)        { self - arg.value }

    method *(Number arg) { MyInt(value - arg.int -> int) }
    method *(arg)        { self * arg.value }

}

#
## Tests:
#
var a = MyInt(2);    # creates a new object of type `MyInt`
a += 7;              # adds 7 to a
say a;               # => 9
say a/2;             # => 4

var b = (a - 3);     # b is of type `MyInt`
say b;               # => 6

assert_eq(b, MyInt(6));

a -= 7;              # a=2
say (a + b);         # => 8 -- the result of (2 + 6)

a += 4;              # a=6
assert_eq(a, MyInt(2)+4);

var err = 0;
try {
    a+b;             # error: Invalid value '12'; must be between 1 and 10
}
catch {
    ++err;
}

assert(err == 1);
