SyntaxError の仕様が Rubinis と MRI とで違う
Rubinis と MRI とでは、SyntaxError クラスの仕様が結構違う。
- MRI では SyntaxError#message にファイル名と行番号が含まれるが、Rubinius では含まれない。
- Rubinius には SyntaxError#file と SyntaxError#line が定義されており、これでファイル名と行番号を取得する。これらは MRI には存在しない。
確認してみる。
$ cat foo.rb if else # syntax error を起こすコード $ cat main.rb begin require 'foo' # syntax error が発生 rescue SyntaxError => ex p ex.message p ex.file if ex.respond_to? :file p ex.line if ex.respond_to? :line end ### MRI では message にファイル名と行番号が含まれる $ ruby main.rb "./foo.rb:1: syntax error, unexpected kELSE" ### Rubinius では message とファイル名と行番号が分離されている $ rubinius main.rb "syntax error, unexpected kELSE" "./foo.rb" 1
これはどう考えても、メッセージとファイル名と行番号が分離している Rubinius のほうが「あるべき姿」だろう。PHP5 でも Exception のメッセージとファイル名と行番号は分離しているから、MRI の Exception は PHP5 以下といえる。残念!
ただし、Rubinius では SyntaxError#file と SyntaxError#line は定義されていても Exception#file と Exception#line が定義されているわけではない。#file と #line が定義されているのはあくまで SyntaxError だけみたい。でもこれは Exception に定義してほしいところだ。PHP5 ではそうなっているから、個人的には Rubinius の Exception は PHP5 以下。残念!ウソ、勘違いでした。
さて、MRI と Ruby とで仕様が違った場合、どうやって spec ファイルを記述すればいいのだろうか。これについては、次のエントリに書く。