■ Ruby でプログラムの行数を

プログラムの場合、コメント部分を除いた行数をしりたいことってありませんか? 行数を数えるということは、 「 wc コマンド 」 で扱っているのですが、ここではプログラムのコメントを除いて行数を数えてみます。

■ 使い方

実行方法は、引数としてファイル名を渡すだけです。 次の実行結果は私の ~/bin にある Ruby スクリプトのコメントを除いた行数です。

$ cd ~/bin
$ lc.rb *.rb
      191 cal.rb
       44 cat.rb
       22 date.rb
      133 df.rb
       93 dircmp.rb
       73 ds2.rb
       43 ds2d.rb
       36 du.rb
        4 env.rb
       70 esc.rb
       22 fold.rb
       22 from.rb
       46 ftime.rb
       21 getconf.rb
      119 hd.rb
       56 head.rb
      170 html_cal.rb
       77 html_lc.rb
      119 last.rb
      301 ll.rb
        5 md5sum.rb
        3 mem.rb
       21 mkdir.rb
       42 mkprof.rb
       10 mp3allinfo.rb
        9 mp3view.rb
      100 nif_cut.rb
       79 nif_get.rb
       27 nif_pop.rb
       51 nif_smtp.rb
       66 nif_sync.rb
       53 ppid.rb
       30 prprof.rb
        9 pwget.rb
        9 re.rb
       36 rename.rb
      140 rg.rb
       38 sdk_lc.rb
        1 sleep.rb
      100 tail.rb
      150 timesort.rb
       76 tree.rb
       14 u2e.rb
       17 u22e.rb
       68 wc.rb
       59 who.rb
       77 wv.rb
       36 xargs.rb
       19 zen.rb
     3007 total

■ ソースコード

Web ブラウザでの表示上は Ruby のスクリプトですが、HTML の特殊文字をエスケープしています。 テキストとしてセーブしてご利用ください。

#! /usr/local/bin/ruby
# /home/tetsu/src/ruby/sdk/lc.rb
# Created: November 06,1999 Saturday 06:06:11
# Author: tetsu(WATANABE Tetsuya)
# $Id: lc.rb,v 1.8 2004/09/16 07:40:41 tetsu Exp $
# usage:

class String
  def lc
    self.gsub(/^\s*\n/, '').count("\n")
  end

  def c_lc
    self.gsub(/\/\*(?:.|\n)+?\*\//, '').lc
  end

  def rb_lc
    self.gsub(/\s*\#.*$/, '').lc
  end

  def java_lc
    self.gsub(/\/\/.*$/, '').c_lc
  end

  def lisp_lc
    self.gsub(/\s*;.*$/, '').lc
  end
end

n_arg = ARGV.size
total = 0

while gets(nil)
  if /\.(.+?)$/ =~ ARGF.filename
    suffix = $1
  end

  n =
    case suffix
    when 'c', 'h', 'cpp', 'C', 'java'
      $_.java_lc
    when 'rb', 'pl', 'awk', 'sh'
      $_.rb_lc
    when 'el'
      $_.lisp_lc
    else
      0
    end

  total += n
  printf " %8d %s\n", n, ARGF.filename
end

printf " %8d total\n", total if n_arg > 1

■ 解説

ファイル名の拡張子から、プログラムのタイプを確認しています。 プログラムのタイプがわかったら、それぞれコメントを除いてから改行の数を数えています。 たったこれだけだったりします。 みなさんも普段使っている言語について、試してみてはいかがでしょう? Ruby や Perl で同じようなスクリプトを書いたときに、記述量の比較などをやってみるとおもしろいかも?

while gets の便利機能を使っているので、一気にファイルをすべて読み込んでしまうという処理がわかりにくいですね。 引数のファイルを直接扱う方法もあるのですが、変数 $_ へ一気に読み込むのに今回のような方法を使っています。

ちなみに、この手のものは、課題としては簡単な部類です。 みなさん、時間があったら自分なりにつくってみてはいかがでしょう? ね。

■ 履歴

1.8 2004/9/16

ARGF.to_s から ARGF.filename へ変更。

1.7 2002/3/31

total がファイルが一つでもでていたので、一つのときは出力しないように。

1.6 2001/4/17

File.basename でファイル名だけ表示していた部分を削除。 PATH が含まれている場合はそのまま表示します。


渡辺哲也(WATANABE Tetsuya): Tetsuya.WATANABE atmark nifty.com