そろそろRuby 1.9に移行しようと思います.ここのところ,1.8と1.9の非互換性について目にする機会がありましたので,それらの情報をもとに,lintと称するにはおこがましいのですが簡単な検証プログラムを作ってみました.
Rubyスクリプトファイルについて,以下のいずれかに該当すれば,指摘します.
- マジックコメントがない.
- $KCODEを使用している(コメントやリテラルでも).
- ASCII以外の文字が含まれている(コメントと=begin〜=endは除外).
- メソッドsize, lengthを使用している.
コマンドライン引数に,対象となるファイル名かディレクトリ名を並べて実行します.なければ,カレントディレクトリを見ます.ディレクトリの場合は,"*.rb" のみです.
ファイル名の代わりに -h か --help を指定すると,ヘルプメッセージを出力して終了します.注意書きが無意味に贅沢です.
「マジックコメントのチェックが単純すぎ*1」「文字列の中の # 以降もコメントとみなす」「文字数を知るメソッドをアドバイスしていない*2」「Ruby 1.9で動作確認していない」など,実用に当たっての問題点は山ほどありますが,自分の書いてきたrbファイルで試して,誤検出がなくなるまでバグをつぶしたので,リリースします.(同日12:40ごろ2か所修正)
#!/usr/bin/env ruby # -*- coding: utf-8 -*- def ruby19lint(file) puts "[#{file}]" # スクリプト取得 content = open(file).read # マジックコメントなし if /coding[:=]/ !~ content puts " マジックコメントがありません。" end # $KCODEの使用 if content.include?("$KCODE") puts " $KCODEが含まれています。" end # ASCII以外の文字 content_lines = content.gsub(/=begin.*?=end/m, "").split(/\n+/).map {|line| line.sub(/\#.*/, "")} unless content_lines.join.gsub(/[\x00-\x7f]/, "").empty? puts " ASCII以外の文字が含まれています。文字列の連結には注意してください。" end # size, lengthの使用 %w!size length!.each do |word| if content.include?(".#{word}") puts " メソッド#{word}を使用しています。" end end end #### main #### if __FILE__ == $0 if ARGV.empty? # 引数なし: カレントディレクトリの*.rb files = Dir.glob("*.rb") if files.empty? puts "*.rbファイルがありません" exit end elsif /^--?h/ =~ ARGV[0] # -h, --help print <<EOS 使用方法: ruby #{$0} ファイルまたはディレクトリ ... これを実行しているRubyのバージョンは#{RUBY_VERSION}です。 EOS print <<'EOS' [Ruby1.9用スクリプトを書くときの注意] 2行目に「# -*- coding: utf-8 -*-」(マジックコメント)を書きましょう。 外部エンコード指定は、1行目(shebang)に「 -Eutf-8」を付け加えるか、 「Encoding.default_external = "utf-8"」という代入文を書きましょう。 文字列のバイト数を知るメソッドには、bytesizeを使いましょう。 EOS exit else # その他: ディレクトリ名ならファイルを探し,そうでないならそのまま files = ARGV.map {|file| test(?d, file) ? Dir.glob("#{file}/**/*.rb") : file}.flatten.compact end # 一つずつチェック files.each do |file| unless test(?f, file) puts "#{file}というファイルはありません" next end ruby19lint(file) end end
自身を検証してみると.「$KCODEが含まれています。」と「ASCII以外の文字が含まれています。文字列の連結には注意してください。」が出ます.
参考にしたもの: