Lightweight Language Lovers

PythonとRubyを比較してみる(Rubyだと日本語の扱いが楽です)

Ruby だと日本語の扱いが楽で、漢字の切り出しや機種依存の判定など基本的なことは Ruby FAQ 日本語の取り扱い にFAQとしてまとめられています。
(実際、SjisChars_py.rb の方では Python と動作を同じにするため、 $KCODE = 'NONE' としてわざわざこの機能を働かなくしています。)

Python でも同様のモジュールが存在するようなのですが http://www.python.jp/Zope/articles/japanese
限られた時間の中いろいろ調べたりインストールする時間が惜しく、1から書いてしまいました。 「楽」というのは、この手間と時間のことも言っています。

では、Ruby版の解説です。
まず、

class SjisChars
  
  $KCODE = "SJIS"
  KU13 = 0x8740..0x879c
  KU89_92 = 0xED40..0xEEFC
  KU115_9 = 0xFA40..0xFC4B
  GAIJI = 0xF040..0xF9FC

ですが、$KCODE で漢字コードを設定しておくことが出来ます。これにより2バイト文字を解釈してくれます。
from..to で、コードの範囲を範囲オブジェクトとして定義しています。Rubyでは定数は大文字で始めます。

  def initialize(chars)
    @chars = chars
    @reKisyu = mkRegexp(KU13, KU89_92, KU115_9)
    @reGaiji = mkRegexp(GAIJI)
  end
  
  def mkRegexp(*ra)
    ra.map! {|r| "[%s-%s]" % [[r.first].pack("n"), [r.last].pack("n")]}
    Regexp.compile(ra.join("|"))
  end

初期化の部分で、インスタンス変数の設定と、コード範囲を表す正規表現オブジェクトの生成を行っています。 Ruby FAQ を見ると、正規表現に漢字を使うことができることがわかります。
コード範囲から、/[始-終]|[始-終]|../ の正規表現を得るのが目的です。

  1. ra.map! ... 配列の各要素(コード範囲)に{ }を適用して更新。
  2. { } ...それぞれのコード範囲(|r|)について、開始値と終了値を漢字に変換後、[始-終]の形に編集。
    • 先頭と最後 ... r.first r.last
    • 数値から漢字に変換 ... pack("n") "n":ネットワークバイトオーダー
    • [始-終]の形に編集 ... "[%s-%s]" %
  3. [%s-%s]それぞれを "|" で join して目的とする正規表現に変換(Regexp.compile)

  def scanSjis
    @chars.split(//).each {|c| yield c, isKanji(c), isGaiji(c), isKisyu(c)}
  end
  
  def isKanji(c)
    c.length == 2    # return true if kanji
  end
  
  def isGaiji(c)
    @reGaiji.match(c) != nil
  end
  
  def isKisyu(c)
    @reKisyu.match(c) != nil
  end

は、文字列から漢字を考慮して切り出して(split(//))、判定しながら yield しています。
ここは、文字列.scan(正規表現) を使うと簡単なのですが、他のプログラムに組み込んで使う場合、 順序を保ったまま判定結果が返ってきたほうが良いので、このようにしています。

hexprint はおまけです。

あと、isKanji 等も1行で書いてしまえるので、もっと短くしようと思えば出来るのですが、可読性を高めるためある程度のところで止めています。
一番の感想は、「しばらく経ってから見ても読むのが苦にならない」ということです。
構文の細かな部分はともかく、文法的なノイズが少ないので文書を読む感覚で流れるように眺めていくことができ、アウトラインを把握するのが実に楽です。私は、Java を読むと、ところどころひっかかってしまう上に、読む量そのものも多いので、特に書いてからしばらく経つと読むのが辛くなってしまいます。

また、完成するまで何度も書き直したのですが、その際、一旦書いたコード片をためらわずに消して書き直すことができました。「書いては消し々」が躊躇なくできるのです。いろいろな手法が気軽に試せるのは、学習効果という面でもLLの非常に良いところです。


CategoryPython CategoryRuby

PythonVsRuby/Ruby2 (last edited 2007-12-29 10:25:13 by ymd)