« 連載: Smalltalk use: better《25》これは要るけどこのほうがいいかな★★ | トップページ | 連載: Smalltalk use: better《27》ここだけの話どこにでもある話★★ »

2006年8月21日 (月)

連載: Smalltalk use: better《26》これは要るけどこれは要らないかな★★

キーワード ◆ do:・inject:into:・reject:・select:

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

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

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

s := 'ABCDE' asOrderedCollection.
Transcript show: s; cr.
s := s reject: [:e | e isVowel].
Transcript show: s
------------------------------ Transcript --
an OrderedCollection($A $B $C $D $E)
an OrderedCollection($B $C $D)

60821areject: を使うと、各要素でブロック式を評価して false となるものだけを要素とする、新たなコレクションが得られます。出力結果を見ると、文字列を構成する各文字が母音でないものだけを要素とする、新たなコレクションが得られるのが分かります。

reject := [:Self :aBlock |
    Self select: [:each |
        (aBlock value: each) == false]].
s := 'ABCDE' asOrderedCollection.
s := reject value: s value: [:e | e isVowel].
Transcript show: s
------------------------------ Transcript --
an OrderedCollection($B $C $D)

60821c ◆ クラス Collection で規定されたメソッド reject: に相当する、ブロック reject について考えます。すると、
 reject value: s value: [:e | ...]
は、
 s reject: [:e | ...]
に相当して、出力結果も同じになるのが分かります。◆

◆ ブロック引数 Self が保持する各要素 each で、ブロック式 aBlock を評価します。false と評価された要素だけを選択します。すべての要素について、メソッド select: に続くブロック式を評価した結果を、リターンオブジェクトとします。

◆ ここで注目したいのは、メソッド select: を再利用していることです。これは、reject: を実現する方法が、select: を介して、do: に依存するものの、特定の種類のオブジェクトには依存しないことを意味します。◆

s := 'ABCDE'.
Transcript show: s; cr.
s := s
    inject: ''
    into: [:acc :e | e asString , acc].
Transcript show: s
------------------------------ Transcript --
ABCDE
EDCBA

60821binject:into: を使うと、各要素でブロック式を評価した結果を累積したものが得られます。出力結果を見ると、文字列を構成する各文字を逆順に並べた、新たな文字列が得られたのが分かります。

inject := [:Self :this :aBlock |
    | next |
    next := this.
    Self do: [:each |
        next := aBlock value: next value: each].
    next].
s := 'ABCDE'.
s := inject value: s value: ''
    value: [:acc :e | e asString , acc].
Transcript show: s
------------------------------ Transcript --
EDCBA

60821d ◆ クラス Collection で規定されたメソッド inject:into: に相当する、ブロック inject について考えます。すると、
 inject value: s value: '' value: [:acc :e | ...]
は、
 s inject: '' into: [:acc :e | ...]
に相当して、出力結果も同じになるのが分かります。

◆ ブロック変数 next は、ブロック式を評価した結果を累積したものを保持します。next に、ブロック引数 this が束縛するオブジェクトを初期設定します。next とともに、ブロック引数 Self が保持する各要素 each で、ブロック式 aBlock を評価します。各要素をたどるごとに、next は、そこで得られたオブジェクトを束縛します。すべての要素について、メソッド do: に続くブロック式を評価した後で、next をリターンオブジェクトとします。

◆ ここで注目したいのは、実引数 Self が保持する各要素を参照する方法が、do: によって決定されることです。これは、inject:into: を実現する方法が、do: に依存するものの、特定の種類のオブジェクトには依存しないことを意味します。

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

|

« 連載: Smalltalk use: better《25》これは要るけどこのほうがいいかな★★ | トップページ | 連載: Smalltalk use: better《27》ここだけの話どこにでもある話★★ »

Squeak/Smalltalk」カテゴリの記事

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

コメント

コメントを書く



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




トラックバック


この記事へのトラックバック一覧です: 連載: Smalltalk use: better《26》これは要るけどこれは要らないかな★★:

« 連載: Smalltalk use: better《25》これは要るけどこのほうがいいかな★★ | トップページ | 連載: Smalltalk use: better《27》ここだけの話どこにでもある話★★ »