447 文字
2 分
rubyでsprintfするときに注意!
概要
- ゼロ埋めされた文字列を、sprintfの第2引数に渡すと、正しい値、間違った値、例外が飛ぶ場合があるので、エラーの特定が困難になる
- 静的解析も難しいから気をつけるしか無いのかな。
実験
Ruby 2.1 on Mac OS 10.0.3 で検証。
7まで正しいけど、それ以降はエラーがでたり、予期しない値が返されたりします。
% ruby sp.rb0000000001000020000300004000050000600007invalid value for Integer(): "00008"invalid value for Integer(): "00009"0000800009000100001100012000130001400015invalid value for Integer(): "00018"invalid value for Integer(): "00019"0001600017000180001900020000210002200023invalid value for Integer(): "00028"invalid value for Integer(): "00029"0002400025000260002700028000290003000031invalid value for Integer(): "00038"invalid value for Integer(): "00039"0003200033000340003500036000370003800039invalid value for Integer(): "00048"invalid value for Integer(): "00049"0004000041000420004300044000450004600047invalid value for Integer(): "00058"invalid value for Integer(): "00059"0004800049000500005100052000530005400055invalid value for Integer(): "00068"invalid value for Integer(): "00069"0005600057000580005900060000610006200063invalid value for Integer(): "00078"invalid value for Integer(): "00079"invalid value for Integer(): "00080"invalid value for Integer(): "00081"invalid value for Integer(): "00082"invalid value for Integer(): "00083"invalid value for Integer(): "00084"invalid value for Integer(): "00085"invalid value for Integer(): "00086"invalid value for Integer(): "00087"invalid value for Integer(): "00088"invalid value for Integer(): "00089"invalid value for Integer(): "00090"invalid value for Integer(): "00091"invalid value for Integer(): "00092"invalid value for Integer(): "00093"invalid value for Integer(): "00094"invalid value for Integer(): "00095"invalid value for Integer(): "00096"invalid value for Integer(): "00097"invalid value for Integer(): "00098"invalid value for Integer(): "00099"原因
Rubyのsprintf(および内部で呼び出される数値変換処理)が、「先頭に0がついた文字列」を8進数(Octal)として解釈しようとするためです。
解決策は、sprintfに渡す前に明示的に10進数のIntegerへキャストすることです。
rubyでsprintfするときに注意!
https://blog.teraren.com/posts/rubyでsprintfするときに注意/