12-4
1つのメソッドに2つの意味を持たせない
「正常なら計算結果、異常なら -1」のように、戻り値に本来の意味とエラー通知の二役を背負わせると、呼び出し側全員にチェックの義務が生まれる。チェックを1か所でも忘れれば、エラー値がただの数値として下流の計算に混ざり込む。エラーは戻り値で表現せず、例外として早く・大きく失敗させる。
家事按分の計算がエラー値 -1 を返す
✕ Bad
def business_portion(expense: int, ratio: float) -> int:
"""家賃などを家事按分して事業分の経費を返す"""
if ratio < 0 or 1 < ratio:
return -1 # エラー値。呼び出し側がチェックする約束
return int(expense * ratio)
total = 0
for expense, ratio in monthly_expenses:
total += business_portion(expense, ratio) # チェック忘れ。-1 が混入✓ Good
@dataclass(frozen=True)
class ApportionRatio:
"""家事按分率(0〜1)"""
value: float
def __post_init__(self) -> None:
if not 0 <= self.value <= 1:
raise ValueError("按分率は 0〜1 で指定してください")
def business_portion(expense: int, ratio: ApportionRatio) -> int:
return int(expense * ratio.value)
total = sum(
business_portion(expense, ratio)
for expense, ratio in monthly_expenses
) # ここに届く ratio は必ず正当。チェック義務が消えるC 言語由来の「エラーコードを返す」習慣の名残がこのアンチパターンを生む。Python なら例外、もしくは「失敗があり得る」と型で示したいなら Result 風に成功・失敗を別の型で返す設計もある。いずれにせよ1つの戻り値に2つの意味を重ねないことが軸。