« 連載: Smalltalk use: better《16》大きいことはいいことかな★ | トップページ | 連載: Smalltalk use: better《18》あなたの大きいは私のとは違うかな★ »

2006年8月 8日 (火)

連載: Smalltalk use: better《17》私より大きいなら私より小さいかな★★

キーワード ◆ <=・>・>=・ダブルディスパッチ・大小比較・文字

※ PDF でご覧になるなら ⇒ 公開日まで、お待ちください。

------------ 序 ------------

◆ 小学校に入学した頃のことを思い出してください。「いちたすいちは、にぃ〜」から始まって、足し算を覚え、やがて引き算を習います。まだ小さな子供たちに「5−3 は?」と尋ねたら「にぃ〜」と笑顔で答えることでしょう。次に「3−5 は?」と尋ねたら「ひけないよ」と真顔で答える子供も中にはいます。その子に「それができるのよ」と教えようとすると「ちいさいのからおおきいのはひけないもん」と怪訝そうな顔をされるかもしれません。そこで「小さな数から大きな数を引けるのよ」と無理強いをすると「オトナってバカじゃない」と相手にされなくなるかもしれません。やがて…(続く)

◆ 負数の概念を導入すると、それまで無意味とされた「小さな数から大きな数を引くこと」にも意義が生まれます。+ や < などの演算は、数だけを対象とするものでした。しかし、その対象を文字列にまで拡張しようとすると、新たな問題に直面することになります。たとえば…

------------ 本文 ------------

◆ 同様に、メッセージセレクター > を使って、2つの文字を大小比較できます。

$a > $b    "false"
$a > $a    "false"
$b > $a    "true"
$A > $a    "false"
$A > $A    "false"
$a > $A    "true"

◆ 2つの文字が同じなら false が得られます。2つの文字が違うなら、< とは、逆の結果が得られます。

◆ 次のような状況で、2つの文字がお互いに大小比較をしているものとします。

60808a ◆ 誰かに「私より大きいか」と問われたら、その相手に「私より小さいか」と問い返すことで、巧みな問題解決(ダブルディスパッチ)を図ります。これは、メソッド > を記述するときに、メソッド < の記述を再利用できることを意味します。

.

.

lt := [:Self :aCharacter |
    Self asciiValue < aCharacter asciiValue].
gt := [:Self :aCharacter |
    lt value: aCharacter value: Self].
gt value: $a value: $b.    "false"
gt value: $a value: $a.    "false"
gt value: $b value: $a.    "true"
gt value: $A value: $a.    "false"
gt value: $A value: $A.    "false"
gt value: $a value: $A.    "true"

> に相当する、ブロック gt について考えます。lt を < と見なすと、
 lt value: aCharacter value: Self
は、
 aCharacter < Self
に相当します。つまり、引数 aCharacter に対して、自分 Self を引数とするメッセージ < Self を送るのと、同等の機能を実現できます。

◆ 同様に、メッセージセレクター >= および <= を使って、2つの文字を大小比較できます。

【注意】何が起こっているのか
次の実行結果を見て、

Transcript show: 3 + 4; space.
Transcript show: 3 + '4'; space.
Transcript show: '3' + 4; space.
Transcript show: '3' + '4'; cr.
Transcript show: 3 < 4; space.
Transcript show: 3 < '4'; space.
Transcript show: '3' < 4; space.
Transcript show: '3' < '4'
# -------------------------------- Transcript --
7 7 7 7
true true false true

'3' < 4 を評価したときだけ、error: 'Instances of SmallInteger are not indexable' となる理由を考えてください。他は何故エラーにならないのでしょうか。

lt := [:Self :aCharacter |
    Self asciiValue < aCharacter asciiValue].
ge := [:Self :aCharacter |
    (lt value: Self value: aCharacter) not].
ge value: $a value: $b.    "false"
ge value: $a value: $a.    "true"
ge value: $b value: $a.    "true"
ge value: $A value: $a.    "false"
ge value: $A value: $A.    "true"
ge value: $a value: $A.    "true"

>= に相当する、ブロック ge について考えます。lt を < と見なすと、
 (lt value: Self value: aCharacter) not
は、
 (Self < aCharacter) not
に相当します。つまり、自分 Self に対して、メッセージ < aCharacter を送った結果を利用して、同等の機能を実現できます。

gt := [:Self :aCharacter |
    lt value: aCharacter value: Self].
le := [:Self :aCharacter |
    (gt value: Self value: aCharacter) not].
le value: $a value: $b.    "true"
le value: $a value: $a.    "true"
le value: $b value: $a.    "false"
le value: $A value: $a.    "true"
le value: $A value: $A.    "true"
le value: $a value: $A.    "false"

<= に相当する、ブロック le について考えます。gt を > と見なすと、
 (gt value: Self value: aCharacter) not
は、
 (Self > aCharacter) not
に相当します。つまり、自分 Self に対して、メッセージ > aCharacter を送った結果を利用して、同等の機能を実現できます。

60808b .

.

.

$a >= $b    "false"
$a >= $a    "true"
$b >= $a    "true"
$A >= $a    "false"
$A >= $A    "true"
$a >= $A    "true"

◆ < とは、逆の結果が得られます。

$a <= $b    "true"
$a <= $a    "true"
$b <= $a    "false"
$A <= $a    "true"
$A <= $A    "true"
$a <= $A    "false"

◆ > とは、逆の結果が得られます。

◆ ここで注目したいのは、メソッド < を除く、他の3つの大小比較に関する記述が、特定の種類のオブジェクトに依存しないことです。これは、任意の種類のオブジェクトに対しても、これらの記述を再利用できることを意味します。すると、任意の種類に対して < を規定するだけで、他の大小比較を再定義する必要がなくなります。つまり、メソッドを記述する手間を、1/4 に軽減できる可能性を秘めています。

==================================
真樹育未 著 ◆ 監修:小泉ひよ子とタマゴ倶楽部

|

« 連載: Smalltalk use: better《16》大きいことはいいことかな★ | トップページ | 連載: Smalltalk use: better《18》あなたの大きいは私のとは違うかな★ »

Squeak/Smalltalk」カテゴリの記事

.連載: Smalltalk use: better」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: 連載: Smalltalk use: better《17》私より大きいなら私より小さいかな★★:

« 連載: Smalltalk use: better《16》大きいことはいいことかな★ | トップページ | 連載: Smalltalk use: better《18》あなたの大きいは私のとは違うかな★ »