diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-23 22:21:57 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-23 22:21:57 +0300 |
| commit | f5d15007d7439d4f3bb7391661031b3445e8ecff (patch) | |
| tree | b0ac06e48b70d443897f89f0a206e8d81529fe92 | |
| parent | d50dec3930ff9ecae590e4ec4f0ddd5581021f1d (diff) | |
refactor: split NewNumber into two constructors (NewNumber, NewNumberWithMetric)
Eliminate confusing variadic *Metric parameter from NewNumber().
Callers either pass nothing (defaults to Cool) or one metric —
variadic implied zero-or-many, causing confusion.
New API:
NewNumber(value, mode) — metric defaults to Cool
NewNumberWithMetric(value, mode, metric) — explicit metric
All callers updated to use the appropriate constructor.
No behavioral changes; same defaults, clearer API.
| -rw-r--r-- | internal/rpn/metric_test.go | 6 | ||||
| -rw-r--r-- | internal/rpn/number.go | 27 | ||||
| -rw-r--r-- | internal/rpn/number_test.go | 2 | ||||
| -rw-r--r-- | internal/rpn/operations_arithmetic.go | 12 | ||||
| -rw-r--r-- | internal/rpn/operations_hyper.go | 14 | ||||
| -rw-r--r-- | internal/rpn/operations_metric.go | 2 | ||||
| -rw-r--r-- | internal/rpn/rpn_parse.go | 4 |
7 files changed, 38 insertions, 29 deletions
diff --git a/internal/rpn/metric_test.go b/internal/rpn/metric_test.go index 48c6e91..69923cb 100644 --- a/internal/rpn/metric_test.go +++ b/internal/rpn/metric_test.go @@ -586,7 +586,7 @@ func TestNumberDefaultMetricIsCool(t *testing.T) { // NewNumber defaults to Cool n := NewNumber(42, FloatMode) if n.Metric() != cool { - t.Errorf("NewNumber().Metric() = %v, want Cool", n.Metric()) + t.Errorf("NewNumberWithMetric().Metric() = %v, want Cool", n.Metric()) } } @@ -614,9 +614,9 @@ func TestNewNumberWithMetric(t *testing.T) { reg := GetMetricRegistry() hr, _ := reg.Find("hr") - n := NewNumber(2, FloatMode, hr) + n := NewNumberWithMetric(2, FloatMode, hr) if n.Metric() != hr { - t.Errorf("NewNumber(metric).Metric() = %v, want hr", n.Metric()) + t.Errorf("NewNumberWithMetric(metric).Metric() = %v, want hr", n.Metric()) } } diff --git a/internal/rpn/number.go b/internal/rpn/number.go index 39aa93b..3f6f004 100644 --- a/internal/rpn/number.go +++ b/internal/rpn/number.go @@ -55,18 +55,27 @@ var _ NumericValue = (*Rat)(nil) var _ StackValue = (*StringNum)(nil) var _ StackValue = (*Symbol)(nil) -// NewNumber creates a Number from a float64 value with the given metric. -// The actual type depends on the current calculation mode. -// If metric is nil or omitted, defaults to Cool. -func NewNumber(value float64, mode CalculationMode, metric ...*Metric) Number { - m := GetCoolMetric() - if len(metric) > 0 && metric[0] != nil { - m = metric[0] +// NewNumber creates a Number from a float64 value with the given mode. +// The actual type depends on the current calculation mode (Float or Rat). +// The metric defaults to Cool (unitless). +func NewNumber(value float64, mode CalculationMode) Number { + if mode == RationalMode { + return NewRat(value) + } + return NewFloat(value) +} + +// NewNumberWithMetric creates a Number from a float64 value with an explicit metric. +// The actual type depends on the current calculation mode (Float or Rat). +// If metric is nil, defaults to Cool. +func NewNumberWithMetric(value float64, mode CalculationMode, metric *Metric) Number { + if metric == nil { + metric = GetCoolMetric() } if mode == RationalMode { - return NewRatWithMetric(value, m) + return NewRatWithMetric(value, metric) } - return NewFloatWithMetric(value, m) + return NewFloatWithMetric(value, metric) } // GetCoolMetric returns the universal default metric. diff --git a/internal/rpn/number_test.go b/internal/rpn/number_test.go index 56ff70b..724e817 100644 --- a/internal/rpn/number_test.go +++ b/internal/rpn/number_test.go @@ -432,7 +432,7 @@ func TestNewNumberWithExplicitMetric(t *testing.T) { reg := GetMetricRegistry() mbps, _ := reg.Find("Mbps") - n := NewNumber(100, FloatMode, mbps) + n := NewNumberWithMetric(100, FloatMode, mbps) val, _ := n.Float64() if val != 100 { t.Errorf("Float64() = %v, want 100", val) diff --git a/internal/rpn/operations_arithmetic.go b/internal/rpn/operations_arithmetic.go index 3215917..70c048a 100644 --- a/internal/rpn/operations_arithmetic.go +++ b/internal/rpn/operations_arithmetic.go @@ -61,7 +61,7 @@ func (o *Operations) binaryMetricOp( return buildError(op, err) } - stack.Push(NewNumber(resultVal, o.GetMode(), resultMetric)) + stack.Push(NewNumberWithMetric(resultVal, o.GetMode(), resultMetric)) return nil } @@ -152,7 +152,7 @@ func (o *Operations) Divide(stack *Stack) error { return buildError("/", err) } - stack.Push(NewNumber(resultVal, o.GetMode(), resultMetric)) + stack.Push(NewNumberWithMetric(resultVal, o.GetMode(), resultMetric)) return nil } @@ -182,7 +182,7 @@ func (o *Operations) Power(stack *Stack) error { return buildError("power", err) } - stack.Push(NewNumber(math.Pow(aF, bF), o.GetMode(), GetCoolMetric())) + stack.Push(NewNumberWithMetric(math.Pow(aF, bF), o.GetMode(), GetCoolMetric())) return nil } @@ -231,7 +231,7 @@ func (o *Operations) Modulo(stack *Stack) error { return buildError("%", err) } - stack.Push(NewNumber(resultVal, o.GetMode(), resultMetric)) + stack.Push(NewNumberWithMetric(resultVal, o.GetMode(), resultMetric)) return nil } @@ -265,11 +265,11 @@ func (o *Operations) FastPower(stack *Stack) error { // Result is unitless (Cool metric) if exp == 0 { - stack.Push(NewNumber(1, o.GetMode(), GetCoolMetric())) + stack.Push(NewNumberWithMetric(1, o.GetMode(), GetCoolMetric())) return nil } resultVal := binaryExponentiationFloat(aF, exp) - stack.Push(NewNumber(resultVal, o.GetMode(), GetCoolMetric())) + stack.Push(NewNumberWithMetric(resultVal, o.GetMode(), GetCoolMetric())) return nil } diff --git a/internal/rpn/operations_hyper.go b/internal/rpn/operations_hyper.go index 6d74a2d..426b471 100644 --- a/internal/rpn/operations_hyper.go +++ b/internal/rpn/operations_hyper.go @@ -54,7 +54,7 @@ func (o *Operations) HyperAdd(stack *Stack) error { return buildError("[+]", err) } - stack.Push(NewNumber(resultVal, o.GetMode(), resultMetric)) + stack.Push(NewNumberWithMetric(resultVal, o.GetMode(), resultMetric)) return nil } @@ -83,7 +83,7 @@ func (o *Operations) HyperMultiply(stack *Stack) error { if err != nil { return buildError("[*]", err) } - stack.Push(NewNumber(product, o.GetMode(), cool)) + stack.Push(NewNumberWithMetric(product, o.GetMode(), cool)) return nil } @@ -134,7 +134,7 @@ func (o *Operations) HyperSubtract(stack *Stack) error { return buildError("[-]", err) } - stack.Push(NewNumber(resultVal, o.GetMode(), resultMetric)) + stack.Push(NewNumberWithMetric(resultVal, o.GetMode(), resultMetric)) return nil } @@ -166,7 +166,7 @@ func (o *Operations) HyperDivide(stack *Stack) error { if err != nil { return buildError("[/]", err) } - stack.Push(NewNumber(result, o.GetMode(), cool)) + stack.Push(NewNumberWithMetric(result, o.GetMode(), cool)) return nil } @@ -195,7 +195,7 @@ func (o *Operations) HyperPower(stack *Stack) error { if err != nil { return buildError("[^]", err) } - stack.Push(NewNumber(result, o.GetMode(), cool)) + stack.Push(NewNumberWithMetric(result, o.GetMode(), cool)) return nil } @@ -249,7 +249,7 @@ func (o *Operations) HyperModulo(stack *Stack) error { return buildError("[%]", err) } - stack.Push(NewNumber(resultVal, o.GetMode(), resultMetric)) + stack.Push(NewNumberWithMetric(resultVal, o.GetMode(), resultMetric)) return nil } @@ -277,7 +277,7 @@ func (o *Operations) hyperLog(stack *Stack, opName string, logFn func(float64) f if err != nil { return buildError(opName, err) } - stack.Push(NewNumber(result, o.GetMode(), cool)) + stack.Push(NewNumberWithMetric(result, o.GetMode(), cool)) return nil } diff --git a/internal/rpn/operations_metric.go b/internal/rpn/operations_metric.go index 949c0c3..c09aad4 100644 --- a/internal/rpn/operations_metric.go +++ b/internal/rpn/operations_metric.go @@ -218,6 +218,6 @@ func (o *Operations) Convert(stack *Stack) error { return buildError("convert", err) } // 6. Push result with target metric - stack.Push(NewNumber(resultVal, o.GetMode(), targetMetric)) + stack.Push(NewNumberWithMetric(resultVal, o.GetMode(), targetMetric)) return nil } diff --git a/internal/rpn/rpn_parse.go b/internal/rpn/rpn_parse.go index ef7be53..eb4f0b9 100644 --- a/internal/rpn/rpn_parse.go +++ b/internal/rpn/rpn_parse.go @@ -331,7 +331,7 @@ func (r *RPN) evaluate(input string, tokens []string) (string, error) { if stack.Len() >= r.maxStack { return "", fmt.Errorf("stack overflow") } - stack.Push(NewNumber(num, r.mode, metric)) + stack.Push(NewNumberWithMetric(num, r.mode, metric)) continue } @@ -343,7 +343,7 @@ func (r *RPN) evaluate(input string, tokens []string) (string, error) { if stack.Len() >= r.maxStack { return "", fmt.Errorf("stack overflow") } - stack.Push(NewNumber(1, r.mode, metric)) + stack.Push(NewNumberWithMetric(1, r.mode, metric)) continue } return "", fmt.Errorf("unknown metric %q in %q", metricName, token) |
