I want to extend Int (or UInt64 specifically, if needed) and do a couple things:
Override the comparison (<=>) operators to compare against the value divided by 1000.
Override the to_s method to format it appropriately.
But you can’t inherit from Int, since it’s a struct. How do you create a new reference type based on another reference type? I’m sure there’s a way, but I got lost. Do I need to box it, even though it’s actual data is still a reference type?
I think your best bet would be to use the decorator pattern and wrap an integer value to expose your API. Then if you wanted you could monkey patch in helper methods like
7.dollars, similar to how
def initialize(@value : UInt64); end
The catch of course being it wouldn’t be compatible with your usual
Int type restrictions, but I don’t think there’s a way around that.
Id consider that a feature. Such value types are distinct types exactly for the reason that they are not just a dimensionless number value.
I appreciate the assistance. I’m attempting to move from Ruby to Crystal for my own personal coding, and learning the differences in best-practices is a challenge that their superficial similarity shrouds.
Also I would use a
struct not a class for this:
def initialize(@value : Int64); end
That way it’s a value type, GC is not bothered and you can still customize the to_s as wanted.
Doing this composition instead of inheritance of Int allows you to not treat values of Dollar as Int which I agree with @straight-shoota is an upside.