Ruby の Exception class を設計し直すとしたら

これの続き。

MRI での Exception の問題点は、「メッセージ」=「表示文字列」となっていることだ。本来ならば、メッセージを get/set するメソッドとは別に、表示文字列を構築するメソッドを用意すべきだった。

class Exception

  def initialize(message)
    @message = message
  end

  attr_accessor :message

  def to_str
    return @message
  end

end


class SyntaxError < Exception

  def initialize(message, filename=nil, linenum=nil)
    super(message)
    @filename = filename
    @linenum  = linenum
  end

  attr_accessor :filename, :linenum

  def to_str
    message = super()
    return "#{@filename}:#{@linenum}: #{message}"
  end

end


ただ、現在の仕様を変更すると影響が大きいだろうから、

  • Exception#message は表示文字列を構築するメソッドということにして、
  • メッセージを取り出す Exception#msg を新たに追加する

という仕様に変更するのはどうだろうか。

class Exception

  def initialize(msg)
    @msg = msg
  end

  attr_accessor :msg

  def message
    return @msg
  end

end


class SyntaxError < Exception

  def initialize(msg, filename=nil, linenum=nil)
    super(msg)
    @filename = filename
    @linenum  = linenum
  end

  attr_accessor :filename, :linenum

  def message
    return "#{self.filename}:#{self.linenum}: #{self.msg}"
  end

end