トラック
/
Factor
Factor
/
演習
/
ドラゴンの子孫
ドラゴンの子孫

ドラゴンの子孫

学習演習

はじめに

タプルは、ほかのタプルを継承できます。TUPLE: child < parent slots ;は、インスタンスがparentのインスタンスでもあるクラスを宣言します。そのインスタンスは、自分自身のスロットに加えて親のスロットも持ち、親のアクセサもそのまま使えます。ちょうど、子で定義されているかのようにです。

USING: accessors ;

TUPLE: animal name age ;
TUPLE: dog < animal breed ;

"Rex" 4 "labrador" dog boa .
! => T{ dog { name "Rex" } { age 4 } { breed "labrador" } }

"Rex" 4 "labrador" dog boa name>> .   ! => "Rex"   (inherited accessor)

boaのスロットの順序

boaコンストラクターが受け取るスロットの順序は、宣言順で、親が先です。上のdogなら、次のようになります。

dog boa ( name age breed -- dog )

孫にあたるpuppy < dog にweeksを加えると、次のようになります。

puppy boa ( name age breed weeks -- puppy )

述語の階層

TUPLE:を宣言するたびに、述語(name?)が生成されます。継承を使うと、述語は入れ子になります。すべての子孫は、祖先の述語を満たします。

"Rex" 4 "labrador" dog boa
dup dog? .        ! => t
dup animal? .     ! => t

逆は成り立ちません。dogでないanimalは、dog?を満たしません。

この先の補足

ジェネリックメソッド(M:。genericsで学びます)も、階層をさかのぼってディスパッチします。animalに対するメソッドは、より具体的なオーバーライドが優先されないかぎり、すべての子孫で呼び出されます。この動きは、この演習のすぐあとにあるboatswains-bilgeで目にすることになります。

説明

ある博物学者が、カルデラの周辺に住むドラゴンたちを分類しています。ドラゴンたちには共通の特徴があります。どのドラゴンにも名前、色、年齢があり、それぞれが独自の方法で特殊化しています。ここでは、ドラゴンのクラスの小さな継承ツリーと、どんな子孫でも年を取らせる1つのワードを作ります。

1. ドラゴンの一族

タプルクラスの継承ツリー全体を最初に定義します(それぞれのコンストラクターは、このあとのタスクで登場します)。

  • スロットname、color、ageを持つdragon。
  • dragonのサブクラスで、スロットflame-tempを追加したfire-dragon。
  • dragonのもう1つのサブクラスで、スロットchill-tempを追加したice-dragon。
  • fire-dragonのサブクラスで、スロットlava-volumeを追加したvolcano-dragon。

次に、dragonに<dragon>コンストラクターを定義します。

"Falkor" "white" 100 <dragon> name>> .   ! => "Falkor"

2. 火を吹くドラゴンたち

fire-dragonに<fire-dragon>コンストラクターを定義します。

"Smaug" "red" 500 1200 <fire-dragon> flame-temp>> .   ! => 1200
"Smaug" "red" 500 1200 <fire-dragon> dragon? .        ! => t

3. 氷を吹くドラゴンたち

ice-dragonに<ice-dragon>コンストラクターを定義します。

"Frosty" "blue" 200 -40 <ice-dragon> chill-temp>> .   ! => -40
"Frosty" "blue" 200 -40 <ice-dragon> fire-dragon? .   ! => f   (siblings)

4. 火山に住むドラゴンたち

volcano-dragonに<volcano-dragon>コンストラクターを定義します。

"Vesuvius" "red" 1000 1500 99 <volcano-dragon> dragon? .       ! => t
"Vesuvius" "red" 1000 1500 99 <volcano-dragon> fire-dragon? .  ! => t

5. どんなドラゴンでも年を取らせる

age-dragonを定義して、どんなドラゴン(またはその子孫)のageスロットも1つ増やします。戻り値はありません。

"Falkor" "white" 100 <dragon> dup age-dragon age>> .   ! => 101

同じワードがどの子孫でも動くはずです。これこそが、共通のアクセサーを使う目的です。

GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Factor Exercism

ドラゴンの子孫を始める準備はできましたか?

Exercismに登録すれば、47個のコンセプト163個の演習、そして本物の人間によるメンタリングとともに、Factorを学んでマスターできます。すべて無料です。