2004年4月15日号

━━━━━━━━━━━━━━━━━━━━━ 2004.04.15 Vol.945 ━━━━━
 ■□■□■
 ■□■□■ 日刊「WEBのツボ!」
 □■□■□              http://www.soho-union.com/
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                             配信部数 3261部

「続 システムはオブジェクト指向 Ruby & Flash」(#007)   
                                                         福井修@Fsys.NET

【○】本日のお題 「 続入力チェックと部品化Mix-in 」━━━━━━━━━━

桜は散ってしまい、もう暑くなってきましたね。
こんにちは、Fsys福井システムリサーチの福井です。

前回「入力チェックと正規表現」注1)にて正規表現のメタ文字について、説明し
ました。最近 思うのですが、それは

    『 繰り返すことの大切さ 』   です。

正規表現など、1度聞いてすぐ使いこなせるものではありません。キー入力も一
度ブラインドタッチの練習をしたらすぐにできるようになる訳ではありません。
同じことですね。何度も使っているうちに、上達するものでしょう。絵が上手な
人、字が上手な人、野球が上手な人、演奏や歌が上手い人、...みんな必ず人よ
りたくさん繰り返し練習しているはずです。

    『 繰り返して上達する 』

「人に負けないこと」というのは、実は「人よりたくさん繰り返したこと」だけ
なのかもしれません。

古いパソコン(Celeron300)を更新しようと思うのですが、DELLからの『 繰り返
し到来するダイレクトメール 』には、恐れ入りまする^^;

話しを戻して、プログラムも結局何度も『 繰り返して上達する 』しか道はあり
ません。

偉そうに言ってますが、私は、プログラムをするより設計書を書く方が、通算時
間は長いので、(プログラマとしてのキャリアは、短いので)バリバリのプログ
ラマの方には、およびもつきません。

が、まあ結構年齢の割りには、いつまでもプログラムをやりたがっていますの
で、好きこそものの上手なれになれたら良いなとは思っています。

Ruby Ruby Ruby.. と繰り返し言っているうちに、Rubyに触れて幸せになれる人
が増えれば良いなと心から思います。

今回は、正規表現を復習して暦の入力チェックからオブジェクト指向の継承を具
体化したところの部品化に役立つMix-inを話題にしています。

ノートPCにWindowsXPという環境で、どんどん楽しいプログラムを進めましょ
う。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■ 正規表現 復習  (くり返しが大事なんですってばぁ^^)
────────────────────────────────────
前回、正規表現で入力チェックの話しをしました。ちょっと復習しておきます。

西暦4桁年で例えば2004年3月30日が "20040330"(固定長)をチェックす
るのには

 /[12]\d\d\d[01]\d[0123]\d/ =~ input

年月日の区切りに"-"ハイフンが使われて "2004-3-30"(長さ可変)であれば

 /^[12]\d{3}-(0?[1-9]|1[0-2])-(0?[1-9]|[12]\d|3[01])$/ =~ input

メタ文字が、使えないと、ちんぷんかんぷんですが、メタ文字が使えると、なる
ほどふむふむとなります^^

電話番号の入力をチェックしてみます。
・ 市外局番と市内局番の区切りをどうする?
・ 携帯などの12桁と従来の11桁とが混在する
・ 番号の区切りをどうする?
いろいろテーマはあります。

まあ簡単なところから

1) 1文字以上の数字のみ受け付けるには

  メタ文字復習
  \d     数字。[0-9] と同じ
  +      直前の表現の1回以上の繰り返し
  なので

  /\d+/ =~ input

  で良かったですね。

  ( 前回は、typo がありましたm(_ _)m )

2) 先頭は、必ず 0 であること(市外局番などを必須に)
 
  メタ文字復習
  ^     行頭にマッチ

  /^0\d+/ =~ input

3) さらに4文字目に - (半角ハイフン)を必須に

  /^0\d\d-\d+/ =~ input

あとはいろいろやってください。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
□ IE では 入力枠で日本語変換を無効に
────────────────────────────────────
 全角が入力される場合をどう扱うかというテーマもあります。
一旦受け付けてから半角に変換してやるというやり方もあります。
その場合には、ハイフンとして"ー"と"−"を認めるなど、考慮すべき事項は、増
えてゆきます。
イントラなどで、ブラウザをIEに限定できると入力枠で日本語変換を無効にする
ことができるので、話しは早いです。

     <input type="text" style="ime-mode:disabled">
                        ^^^^^^^^^^^^^^^^^^^^^^^^^
このように<input>タグ内で style="ime-mode:disabled" を入れるだけです。

これだけで、どれほど入力する側も受け付ける側も便利になることか!
この技は、もっと広まって欲しいものです。


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
□ 月の最大日 
────────────────────────────────────
暦の扱いでは、"2004-2-29"はOKで"2005-2-29"はダメといううるう年の判定や 
1,3,5,7,8,10,12月は、31日までというチェックは避けて通れないのですが全部
を正規表現でチェックするのは、無理です。

まとめてエレガントにチェックするには、「月の最大日」を求めてチェックする
方法が一発です。
すこし正規表現からは脱線しますが、これを片づけておきましょう。

module Input_check

  #年月よりその月の日付のmaxを得るメソッド
  #次の月の1日の前の日付けが、これすなわちその月の最大日
  def days_in_month(year,month)
    month += 1
    if month == 13
      year += 1
      month = 1
    end
    (Time.local(year, month, 1) - 24*60*60).mday
  end
end

Timeクラスが、標準でもっているところのローカルタイムの日付けからTimeオブ
ジェクトを生成するメソッドを利用しています。
Timeオブジェクトのmdayメソッドでは、月の日(1-31)を返してくれます。
うるう年の判定や 1,3,5,7,8,10,12月は、31日までという判定は、Timeオブジェ
クトが引き受けてくれているので、それを利用しないのはもったいないのです。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■ 共通部品化 Mix-in方式
────────────────────────────────────
 ここで、オブジェクト指向の話しに入ります。オブジェクト指向では、カプセ
ル化や継承、多態性(ポルモーフィズム)を利用して、共通部品を作りやすいの
で、従来の手続き型に比較して有利であるとの話しを思い出して下さい。注2)


 オブジェクト指向の特長である『継承』を実装する際には、複数クラスから
『継承』するにはどうする?という問題に直面します。

システムはオブジェクト指向 Ruby & Flash(#004) 「Flash ActionScriptをオブ
ジェクト指向から見ると」注3) で既報ですが、日経バイト2002年10月号,P.88
で指摘されている「Javaの知られざる欠陥」注4)中でも挙げられています。
「  (1)オブジェクトではないデータ型があること
    (2)いろいろな型で使えるクラスを作れない 
    (3)二つ以上のクラスの実装を継承できないこと 」
    
Rubyの特長としてこの問題を『 Mix-in方式 』で解決しています。
Mix-in方式では、そのクラスで、メソッドを定義しなくても、メソッドを定義し
たmoduleをインクルードすれば、そのメソッドが使えるようになります。
(これが、めちゃ便利!!)

上の module Input_check を days_in_monthメソッドを使いたい箇所のクラスに
includeしてやれば良いのです。

  class Hoge < Superhoge
    include Input_check
       :
  end

この例では クラスHogeは 親クラスSuperhogeを継承しているので、別のクラス
から継承できません。(RubyJava同様 多重継承を許していないからです)
では、新たなメソッドは、自分の中で定義するしかないのでしょうか?
どこか別に共通に定義した分を利用することはできないのでしょうか?

その答えは『可能』です。
 『 Mix-in方式 』では、他で開発したモジュールを部品として取り込める(多
 重継承をうまく避けながら、複数の部品を使える)のです。

Mix-in方式の説明は、ここ 注5) でもみつかりました。が教科書 注6) を読むの
が一番かもしれません。

P.195を引用します。
「 モジュールをMix-inとしてクラスに「混ぜ込む」ためにはincludeを使いま
  す。inclideは、Classクラスのメソッドで、あるモジュールで定義されている
  メソッドや定数を対象のクラスやモジュールに混ぜ込みます。正確には、その
  クラスとスーパークラスの間にそのモジュールと同じ性質を持つ隠れたクラス
  を挟み込んだのと同じ様な働きをします。..」

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■ まとめ
────────────────────────────────────
 今回は 正規表現を少し復習し、入力チェックの話題の続きで多重継承の実装の
ひとつである Mix-inなどを解説しました。
moduleのincludeというのもはじめは「それがどうした」という感じだったので
すが、使っているうちに、「これってすごいやん」と言いたくなってきます。

    『 繰り返して磨けば光る! 』 です。

で
<input type="text" style="ime-mode:disabled">も3回出てくると、印象に
残ったでしょうか。


またまたいろいろな要素が出てきましたね。一歩一歩進みましょう。

また 次回をお楽しみに。

  
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
※ 注釈、資料、参考情報
────────────────────────────────────
注1) 続 システムはオブジェクト指向 Ruby & Flash (#006)   
    「入力チェックと正規表現http://www.melma.com/mag/02/m00020302/a00000732.html

注2) システムはオブジェクト指向 Ruby & Flash (#002)   
    「オブジェクト指向とは」
http://www.melma.com/mag/02/m00020302/a00000602.html

注3) システムはオブジェクト指向 Ruby & Flash (#004) 
    「Flash ActionScriptオブジェクト指向から見ると 」
http://www.melma.com/mag/02/m00020302/a00000621.html

注4) 日経バイト Javaの知られざる欠陥 (閲覧には登録が必要)
http://itpro.nikkeibp.co.jp/members/NBY/techsquare/20030117/1/
http://itpro.nikkeibp.co.jp/members/NBY/techsquare/20030117/2/
http://itpro.nikkeibp.co.jp/members/NBY/techsquare/20030117/3/

注5) 続Ruby入門の第6章 モジュール
http://www.jaist.ac.jp/~m-hatake/ruby/ruby2.htm

 こちらも参考に
 ・ Ruby入門
http://www.jaist.ac.jp/~m-hatake/ruby/ruby2.htm
 ・ 続々Ruby入門
http://www.jaist.ac.jp/~m-hatake/ruby/ruby3.htmRuby User's Guide - モジュール
http://www.ruby-lang.org/ja/uguide/uguide17.html

注6) 『オブジェクト指向スクリプト言語Ruby』ISBN4-7561-3254-5
まつもとゆきひろ,石塚圭樹共著 576ページ(株)アスキー
http://www.ascii.co.jp/books/ 

【プロフィール&近況】
福井 修 ( FUKUI Osamu ) o-fukui@po.iijnet.or.jp
福井システムリサーチ http://fsys.net/  主幹。システム構築歴27年。
システム構築エキスパート
日本Linux協会、神戸商工会議所情報処理学会、関西IT共同体 会員
関西ソーホ・デジタルコンテンツ事業協同組合デジタルハリウッド神戸校 Java講師