#!/usr/bin/ruby

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

subset Integer    < Number  { .is_int }
subset MyIntLimit < Integer { . ~~ (1 ..^ 10) }

class MyInt(value < MyIntLimit) {

    method ==(Number x) { value == x }
    method ==(MyInt  x) { value == x.value }

    method to_s      { value.to_s }
    method get_value { value.get_value }

    method AUTOLOAD(_, name, *args) {
        var results = [value.(name)(args.map {|n| Number(n) }...)]
        results.map{|r| r.kind_of(Number) ? MyInt(r.int) : r}...
    }
}

#
## 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

assert_eq(a, MyInt(9))
assert_eq((a/2), MyInt(4))

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

assert_eq(b, MyInt(6))
assert_eq(a.as_hex, "9")
assert_eq("#{b}", "6")
assert_eq(b.class, "MyInt")

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

assert_eq(a, MyInt(2))

a += 4              # a=6

assert_eq(a, 6)
assert_eq(a, MyInt(6))
assert_eq("#{a}", "6")
assert_eq(a.class, "MyInt")

var error = 0;
try {
    say a+b             # error: class `MyInt` does not match MyInt(12)
}
catch {
    error += 1
}

assert_eq(error, 1)

say "** Test passed!"
