| 1 | use v6-alpha; |
|---|
| 2 | |
|---|
| 3 | class Unit { |
|---|
| 4 | has $.q is rw; |
|---|
| 5 | |
|---|
| 6 | method set ($self: Num $value) { $.q = $value; $self; }; |
|---|
| 7 | multi method string ($self:) {$self.q ~ $self.abbreviation; } |
|---|
| 8 | multi method string ($self: Num $prec) { |
|---|
| 9 | return $self.q.fmt('%.' ~ $prec ~ 'f') ~ $self.abbreviation; |
|---|
| 10 | } |
|---|
| 11 | |
|---|
| 12 | method toBase($self:) { $.q * $self.baseFactor } |
|---|
| 13 | method fromBase($self:) { $.q / $self.baseFactor } |
|---|
| 14 | |
|---|
| 15 | method setFromBase($self: Num $value) { $.q = $value / $self.baseFactor; } |
|---|
| 16 | method baseFactor() { 1; } |
|---|
| 17 | } |
|---|
| 18 | |
|---|
| 19 | multi sub *infix:<+> (Unit $a, Unit $b) { |
|---|
| 20 | die unless $a.type eq $b.type; |
|---|
| 21 | my $new = $a.clone(); |
|---|
| 22 | # wierd hack around a wierd error. |
|---|
| 23 | my $aVal = $a.toBase(); |
|---|
| 24 | my $bVal = $b.toBase(); |
|---|
| 25 | $new.setFromBase( $aVal + $bVal); |
|---|
| 26 | return $new; |
|---|
| 27 | } |
|---|
| 28 | |
|---|
| 29 | multi sub *infix:<-> (Unit $a, Unit $b) { |
|---|
| 30 | my $new = $a.clone(); |
|---|
| 31 | # wierd hack around a wierd error. |
|---|
| 32 | my $aVal = $a.toBase(); |
|---|
| 33 | my $bVal = $b.toBase(); |
|---|
| 34 | $new.setFromBase( $aVal - $bVal); |
|---|
| 35 | return $new; |
|---|
| 36 | } |
|---|
| 37 | |
|---|
| 38 | class Distance is Unit { method type () { 'distance'} } |
|---|
| 39 | |
|---|
| 40 | multi sub postfix:<ft> (Num $value) { Feet.new().set($value) } |
|---|
| 41 | class Feet is Distance { |
|---|
| 42 | method abbreviation () { "ft" }; |
|---|
| 43 | method baseFactor () { 0.3048 }; |
|---|
| 44 | } |
|---|
| 45 | |
|---|
| 46 | # not m, as that's taken by m// |
|---|
| 47 | multi sub postfix:<m> (Num $value) { Meter.new().set($value) } |
|---|
| 48 | class Meter is Distance { |
|---|
| 49 | method abbreviation () { "m" }; |
|---|
| 50 | # no base factor because it IS the base Unit |
|---|
| 51 | } |
|---|
| 52 | |
|---|
| 53 | multi sub postfix:<km> (Num $value) { Kilometer.new().set($value) } |
|---|
| 54 | class Kilometer is Distance { |
|---|
| 55 | method abbreviation () { "km" }; |
|---|
| 56 | method baseFactor () { 1000 }; |
|---|
| 57 | } |
|---|
| 58 | |
|---|
| 59 | multi sub prefix:<~> (Unit $unit) { $unit.string; } |
|---|
| 60 | #multi sub infix:<`> (Int $value, Unit $unit) { $unit.set($value); }; |
|---|
| 61 | |
|---|
| 62 | my $feet = 5ft; |
|---|
| 63 | my $meter = 6m; |
|---|
| 64 | say $feet.string(); |
|---|
| 65 | say $meter.string(); |
|---|
| 66 | # my $z = $x.to($y); |
|---|
| 67 | # say $z.string; |
|---|
| 68 | |
|---|
| 69 | my $add = $feet + $meter; |
|---|
| 70 | say $add.string(2); |
|---|
| 71 | |
|---|
| 72 | my $add2 = $meter + $feet; |
|---|
| 73 | say ~$add2; |
|---|
| 74 | |
|---|
| 75 | my $sub = $meter - $feet; |
|---|
| 76 | say ~$sub; |
|---|
| 77 | |
|---|
| 78 | my $kilometer = 1000km; |
|---|
| 79 | $add = $kilometer + 90ft; |
|---|
| 80 | say $add.string(2); |
|---|
| 81 | |
|---|
| 82 | my $add = 1ft + 1m; |
|---|
| 83 | say $add.string(2); |
|---|