hitode909の日記

趣味はマリンスポーツですの日記です

Rubyのプログラムのソースコード中のトークンの出現回数を調べてみる

Ruby1.9にはRipperというライブラリが添付されていて,これを使うとRubyソースコード構文解析できる.

Ripperを使ってソースコード中のトークンの出現回数を数えてみた.


このようなスクリプトを書いた.

#!/usr/bin/env ruby1.9
# -*- coding: utf-8 -*-
require 'ripper'
 
result = Hash.new{ |h,k| h[k] = 0 }
 
ARGF.read.split(/\s/).each{ |file|
  Ripper.tokenize(open(file, "r:utf-8").read).each{ |token|
    result[token] += 1
  }
}
 
result.to_a.sort_by{ |pair| pair[1] }.reverse.each{ |pair|
  token, count = *pair
  puts "#{count} #{token.inspect}"
}

入力されたソースコードをトークンごとにばらして,出現回数が多い順に出力する.


このスクリプトに,標準的なプログラムのソースコードと,特定の機能に特化したプログラムのソースコードを入力して,比較してみる.

Ruby1.9.1の添付ライブラリ

添付ライブラリは模範的で標準的なソースコードなはず.

% cd /opt/local/lib/ruby1.9/1.9.1
% echo *.rb */*.rb | ~/count_token.rb > ~/ruby1.9_count.txt  

全ての結果は以下.

結果の一部

93238 " "
72237 "\n"
23992 "    "
19925 "."
17752 "      "
16323 ","
16208 ")"
16110 "("
15704 "  "
14598 "\""
13274 "="
12926 "end"
8703 "        "
8603 "'"
5966 "def"

空白文字が多いが,Rubyっぽいキーワードが上のほうに出てきている.

Termtterのソースコード

TermtterはTwitterクライアントで,特定の機能に特化しているので,その分野特有のトークンが出るはずだと思った.

% cd co/termtter
% git ls-files | grep "\.rb" | ~/count_token.rb > ~/termtter_count.txt 

結果は以下.

上のほうは添付ライブラリとそう変わりないが,20位を越える辺りから,差が出た.

340 "config"
319 "Termtter"
316 "arg"
305 "Client"
289 "name"
234 "plugins"

通常のアプリケーションには含まれない,Termtterや,Client,pluginsといったトークンが上位に現れている.
これを見ると,Termtterという名前のクラスか何かがあり,configに設定を格納することができて,プラグインをロードできそう,というくらいは分かる.

考察

  • 出現回数が多いトークンほど重要なように見える
  • アプリケーションの特色となるトークンがある場合,上のほうに出現している
  • 出現回数を見るだけで意外と有意な情報を得ることができた
  • 数えた結果を統計的に処理すれば,知らないソースコードを読む前に,トークンの出現回数の特徴から,プログラムの中身を推測できるようになるのではないか
  • Ruby以外でも同様の手法を使えそうだが,他の言語の場合は,Ripperのようにちゃんと分けるのが難しそう
  • 知らない言語を勉強する場合,上から順に学んでいけばよさそう