レッスン16

正弦(sin)表デモ

Mopsプログラミングの精髄を学ぶ最良の方法は、既存のプログラムを研究し、それから、 メソッドを変更し、新たなサブクラスを定義し、新しいMopsワードとオブジェクトを生成し、 メモリー内の様々なオブジェクトへとメッセージを送ることによって、ゆっくりとプログラムを自己流に変えていくことです。

引き続くいくつかのレッスンでは、二つのプログラムを研究します。 そのソースファイルは‘Demo folder’フォルダーに、通常の書類ファイルとして含まれています。 第一のものはSinと呼ばれています(ソースファイルは"Sin")。 もうひとつはTurtleです(ソースファイルは"Turtle")。 後でコード内容を提示しますが、このレッスンでの議論を追いかけるためにソースコードを1コピー印刷したいと思うかもしれません。 SinはMopsのアレイ型データ構造の働き方についての優れた実例となっています。 Turtleはクラス-オブジェクト関係の理解を強化します。

以下のレッスンでのソースコードに関する議論では、コードは行の左側余白に行番号が示されるでしょう。 これらは、様々な演算を説明するときにコードの正確な行を参照することがより容易になるようにするためだけに、ここで挿入されたものです。 Mopsコード内には、もちろん、行番号はありません(ただ、QuickEditをお使いなら、ファイルのどの辺りにいるのかは大体わかります)。

正弦表を構築する

先に進む前に、これらのプログラムが何をするために設計されたものなのかを理解しておくことは重要です。 どんなものでも自分の書くMopsプログラムの遂行内容とゴールは明確に規定しておくべきであるのと同様です。

Sinは実際に、あなたが後になって書くであろうようなものも含むたくさんのプログラムに対して一般的に有用な目的を持った礎石となりうるものです。 その目的とは、正弦値の参照表を生成し、加えて、プログラムの後の部分でサインおよびコサインの値を素早く単純な方法で取り出す、というものです。

三角関数に関する知識が少し錆び付いているようなら、角のサイン(正弦)値は角度計測を扱うのに便利な方法といえます。 数学的には、ある角のサインは、その角を含む仮想的な直角三角形の斜辺に対するその角の反対側の辺の長さの比です。 例えば、角をθ(シータ)と名付ければ、θのサインはAの長さ(シータの対向辺)をC(斜辺)の長さで割ったものになります。


0度から360度までの sin θ の可能な値を全て計算して、その結果を表示したならば、その値は、円の全体を通じて増えたり減ったりし、二つの象限では負の値をとることがわかるでしょう。

しかし、例えば、サインの値が0.5になる角度は二つありうることに注意してください。第一象限ではそれは30度です。第二象限では150度になります — これは"ゼロ"になるところ(180度ですが)から30度離れたところです。言い方を変えれば、sin の値は第一象限と第二象限とでは、90度の印のところで分けて、互いに鏡像対称になっているということです。

同様のことは第三象限と第四象限の間にも言えます。そして、前半部分(0-180度)と後半部分(180-360度)との関係は、後半部分は前半部分の鏡像でありながら値の符号が負になっています。 ですから、0-90度間のsinの値の表が得られれば、残りの象限の対応する値を得るのは比較的容易であることになります。Sinプログラムはこの表と計算の両方を扱います。

グラフィックスプログラムの中には、スクリーン上に精巧な形象を描画するために、サインとコサインの両方を取り出す必要があるものがあるでしょう。Sin(とそのクラスTrigTable および Angle)は、将来のあなたのプログラムのために、きっと役に立ちます。

Sinは第二のプログラムTurtleによってしばしば呼び出されることになるでしょう。 Turtleの意図は二つあります。第一に、それはペン(PEN)と多角形(POLY)のクラスを生成し、 これらはLogo類似の環境を開発する実験に用いられます。 Turtleは自身が(Sinに由来する定義に沿って)生成したペンと多角形を用いて、いくつかの精巧なグラフィックスをスクリーン上に描き出します。 あとで分かるように、これらのグラフィックスは、このチュートリアルの最後の章の主題となっている、さらなる第三のデモンストレーションプログラムに統合されることになります。

この「ビルディングブロック【建築素材?】」アプローチはMopsプログラムの設計ではよくある戦略です。SinやTurtleの諸部分ような、注意深く、発生的に設計されたビルディングブロックは、広く様々なプログラムで利用可能であり、信頼できるブロックからなるライブラリーを基に、より容易にかつより迅速に、プログラムを組み立てることができるようになるのです。

正弦表の働き方

Sinのソースコードから始めましょう。第1行から第76行までの番号が振られています。:
1	\ These classes obtain the sine and cos of an angle by table lookup.
2	\ Modified from the original Neon version by Mike Hore.
3
4	\ The main class is ANGLE, which has SIN: and COS: methods that look
5	\ up a table defined with the TRIGTABLE class.
6
7
8	need	struct1
9
10
11	:class TRIGTABLE super{ wArray }
12
13		4	wArray AXISVALS		\ 90 degree values
14
15	:m SIN: { degree \ quadrant -- sin }
16	\ Looks up a sin * 10000 of an angle
17
18		degree 360 mod			\ Put angle in range -359 to +359
19		dup 0< IF 360 + THEN		\ Now 0 to +359
20		90 /mod		\ Convert angle to range 0-89 and get quadrant
21		-> quadrant   -> degree
22		degree				\ Test for an axis
23		NIF	quadrant at: axisVals	\ If an axis, get value
24		ELSE	quadrant 1 and		\ True for "mirror" quadrants 1 and 3
25			IF	90 degree -	\ Create mirror image
26			ELSE	degree
27			THEN
28			at: self			\ Get sin for this degree
29			quadrant 2 and		\ True for "negative" quadrants 2 and 3
30			IF negate THEN
31		THEN ;m
32
33	:m COS:	\ ( degree -- cos )
34		90 +   sin: self ;m		\ Cos is sin shifted by 90 degrees
35
36	:m CLASSINIT:
37		0	 0 to: axisvals
38		10000	 1 to: axisvals
39		0	 2 to: axisvals
40		-10000 3 to: axisvals ;m
41
42	;class
43
44	90 TrigTable SINES  	\ system-wide table of sines
45
46	: 's		\ ( val degree -- )    Fills a Sin table entry
47		to: sines ;
48
49	00000 00 's   00175 01 's   00349 02 's   00524 03 's   00698 04 's
50	00872 05 's   01045 06 's   01219 07 's   01392 08 's   01571 09 's
51	01736 10 's   01908 11 's   02079 12 's   02250 13 's   02419 14 's
52	02588 15 's   02756 16 's   02924 17 's   03090 18 's   03256 19 's
53	03420 20 's   03584 21 's   03746 22 's   03907 23 's   04067 24 's
54	04226 25 's   04384 26 's   04540 27 's   04695 28 's   04848 29 's
55	05000 30 's   05150 31 's   05299 32 's   05446 33 's   05592 34 's
56	05736 35 's   05878 36 's   06018 37 's   06157 38 's   06293 39 's
57	06428 40 's   06561 41 's   06691 42 's   06820 43 's   06947 44 's
58	07071 45 's   07193 46 's   07314 47 's   07431 48 's   07547 49 's
59	07660 50 's   07771 51 's   07880 52 's   07986 53 's   08090 54 's
60	08192 55 's   08290 56 's   08387 57 's   08480 58 's   08572 59 's
61	08660 60 's   08746 61 's   08829 62 's   08910 63 's   08988 64 's
62	09063 65 's   09135 66 's   09205 67 's   09272 68 's   09336 69 's
63	09397 70 's   09455 71 's   09511 72 's   09563 73 's   09613 74 's
64	09659 75 's   09703 76 's   09744 77 's   09781 78 's   09816 79 's
65	09848 80 's   09877 81 's   09903 82 's   09925 83 's   09945 84 's
66	09962 85 's   09976 86 's   09986 87 's   09994 88 's   09998 89 's
67
68	: SIN    sin: sines   ;
69	: COS    cos: sines   ;
70
71	:class   ANGLE super{ int }
72
73	:m SIN: get: self   sin ;m
74	:m COS: get: self   cos ;m
75
76	;class

1行目から5行目まで

これらの行は、ソースコードの最初に付された普通の英語で書かれた注釈です。 このモジュールが何をするのか、誰がそれを書いたのか、その主要な特徴は何か、を説明しています。 この特定のモジュールは、Turtleが複雑な曲線やグラフィックスを描画するのに利用する正弦表を生成します。 ここでは"バックスラッシュ"(\)タイプのコメントを用いています。 バックスラッシュだけからなるワードによって、Mopsはその行の残りを無視します。

8行目

この行はMopsにファイル"Struct1"(フォルダー‘Extras’に含まれています)を、もしも既にロードされていなければ、ロード(コンパイル)します。 このファイルはクラスwArrayの定義を含んでいます。それがここで必要になるのです。 ‘need myfilename’構文の効用は、ファイルmyfilenameが既にロードされているかどうか気にしなくても良いということです。 実際、それは、プログラム開発の段階によって、ロードされているときも、されていないときもあるでしょう。 NEED構文を用いるということは、このソースファイルが必要であることを明示的に宣言することを意味します。; 細かい点はMopsが面倒を見てくれます。

11行目

ここからTrigTableクラスのためのクラス定義が始まります。 このクラスは、正弦表(44-66行で生成されます)のサインの値を捜すために従うべき規則と手続を確立します。 正弦表は固定小数点数のサイン値(0から10,000までの値を取ります)のリストになりますから、 各項目につき2バイトのデータが利用できるでしょう(10進の10,000は16進で2710であり、16進数は2桁がちょうど1バイトメモリー分に当たります。)。クラスTrigTableはクラスwArrayのサブクラスとして定義されています。

スーパークラスwArrayのソースコードリスト(ファイル"Struct1"にあります)を見れば、 wArrayは指標付き(Indexed)クラスとして定義されていることがわかるでしょう。:
:class	WARRAY  super{ indexed-obj }  2 indexed
クラスが指標付きであるということは、そのクラスから生成されるオブジェクトはすべて、そのプライベートデータのために確保しておくべきメモリー領域がどれくらいの大きさになるのか(あるいは、何個のデータスロット【箱】が取り置かれるべきか)を、明示的に宣言しなければならないということを意味します。 wArrayクラスの定義にある数値2は、各スロットが2バイト幅であるべきことを意味しています。指標付きクラスからオブジェクトを生成するそのときには、そのコードの行はそのオブジェクトに必要となるデータスロットの数で始まらなければなりません(各スロットは固有の指標値に関連づけられています)。 上のSinプログラムの44行目では、TrigTableクラスから生成されるオブジェクトSinesは、 90個のスロットを確保しています。;各スロットは2バイト幅です。というのは、TrigTableはwArrayの2バイト幅指標付きクラスの挙動を継承しているからです。 このクラス定義の残りの部分を説明して、いくつかの実用的な例を観察すれば、指標付けの意味はもっと明瞭になるはずです。

13行目

この行はTrigTableクラスのオブジェクトのためのインスタンス変数(ivar)を確立しています。 TrigTableから生成される全てのオブジェクトは、ここで生成されるアレイと上で述べた指標付きデータのためのスペースを確保します。 アレイの前にTrigTableクラスの全てのインスタンスに含まれる要素の個数を置きます(今の場合4です)。

このアレイAxisValsは、2バイト区画の4要素アレイです。このアレイに格納される値の範囲は、-10,000から+10,000までです(このプログラムがサイン値を示すのに用いる整数値です)。 これら4っつのセルにある値は、90度の倍数(0, 90, 180, および 270度)の正弦値(の10000倍)となるでしょう。これらは、このクラス定義の後の部分の正弦値の計算に一定の役割を果たします。

四つの象限とそれらの符号および正弦値のまとめは、次のようになります。:

象限 符号 角度範囲 正弦値の範囲
0 + 0 から 90 0 から 10000
1 + 90 から 180 10000 から 0
2 - 180 から 270 0 から -10000
3 - 270 から 360 -10000 から 0
私達の四つの象限を参照する場合は、ここで表示したように参照します(0から数えていきます。自然数1からではありません。)【つまり、数学では、普通、象限は1,2,3,4と数えますが、プログラミングの都合上、ここでは0,1,2,3と番号を振ってそれを用いるということです。】

15行目

SIN:メソッドの定義がここから始まります。 注釈‘{ degree \ quadrant -- sine }’は、このメソッドにはひとつの名前付き入力引数DEGREEと、ひとつの局所変数QUDRANTがあるということを示しています。 そのような変数への参照は、その名前を用いて行われ、スタック上の在処によるのではないので、 続くいくつかのコードで正弦値を計算する過程でたくさんのスタック操作が省略できる結果になっています。 この定義の範囲内で、QUADRANTはそこで正弦値が計算される象限の値 (0, 1, 2,3)を格納するのに用いられます。

この中括弧(捩れ括弧)による注釈は、そのメソッドの実行のスタックへの効果の記録という目的にも役立っています。 それは、もしもあるメッセージにおけるセレクターにしたがってこのSIN:メソッドを用いるならば、そして、 角度に当たる数値を引数として渡したならば(例えば、‘90 SIN: myobject’のように)、 このメソッドの計算が完了したときには、対応する正弦値がスタック上の残るだろうということを告げています。

16行目

このコメントは、このメソッドで何が起るのかをおしえています。: このプログラムは、ある角(度)の正弦値を見つけ出します。 計算においては、実際の正弦値は(黙示的に)因子10000がかけられています。 正弦表の全ての正弦値は、したがって、整数になっています。

18行目から34行目まで

次は、実際の計算と正弦値の取りだしです。 この計算における数学はIF...THEN決定構造と強く結びついているので、 各ステップでスタック上に何が起っているのかをたどり、ならんで、なぜ様々な演算操作が実行されているのかを説明しようと思います。

概観しましょう。数学的計算はまず角度の値を、0-359の範囲内になるように変換します。 負の数値や360以上の大きさを持つ角度も許されるようにします。 ひとたび角度が"正規化"されれば、それは0-89の範囲内の同値な角度に変換され、鏡像計算や符号の決定のために象限が保存されます。 軸上の角度(0, 90, 180または 270)に対しては、 正弦値はivar AxisValsからとられます。 その他の場合は、TrigTableアレイ上で探索が実行されます。

このセクションでの決定過程の実行をよく理解するため、角度が90度未満のとき、ちょうど180度のとき、3象限(角度が270と360の間のどこか)にあるとき、それぞれを試した場合について、 スタック上の値に対して何が起るのかを追跡することにしましょう。 しかし、これをきちんと行うには、SIN:メソッドが取り出すべき値はアレイにどのように詰められているのか、 そしてそれらの値は何を意味しているのかについて説明を続けるべきでしょう。

36行目から40行目

メソッドCLASSINIT:は特殊なメソッドで、現在のクラスのあるオブジェクトが生成されるときにいつも実行されます。 今のこのCLASSINIT:における演算は、四つのメッセージを含んでおり、すべてはTO:演算です。 これらのメッセージのTO:セレクターは、その受け手のクラスにおけるTO:メソッドで定義されています。 受け手はivar AxisValsですから、問題のクラスはwArrayです。

アレイに対しては、メソッドAT:およびTO:は、通常のスカラーオブジェクトに対するGET:およびPUT:に相当します。 それらは、開始時のスタック上に、どのアレイ要素にアクセスすべきなのかを示す指標値を期待します。

TrigTableクラスが定義されたので(10行目から42行目までの全コード)、そのクラスのオブジェクトとして、実際のアレイをメモリー上に生成できるようになりました。 44行目の陳述はまさに、Sinesという名前の指標付きアレイオブジェクトを確立しています。 これはivar AxisValsに加えて90個の値を格納することができます。 この時点では、Sinesアレイの90個の小包には何の値も入力されていませんが、 スペースはとってあり、値を組み込む準備はできています。 このアレイはTrigTableのスーパークラスであるwArrayクラスで定義されたアレイの特性を保持しています。

46行目から66行目

49行目から66行目までの数値の羅列は恐ろしげに見えるかもしれませんが、実際にはこれらは三角関数の教科書の終わりにあるような参照表のコンピュータ版となるものの値でしかありません。46行と47行はMopsワード 'sを定義しています。 (アポストロフ【sの前の点】は"ティック"と読みます)。 このワードは、CLASSINIT:に例示された格納演算TO:と類似の事柄を遂行します。 ここではその格納はSinesという名前のTrigTableのインスタンスに対して行われるわけです。 SinesがTO:をセレクターとするメッセージを受けたときには、Sinesはまずそれ自身のクラス(TrigTable)に適合する定義を捜します。そこには定義はありませんから、Sinesは、今度はそのスーパークラスwArrayに捜しにいきます。そこでTO:メソッドを見つけるわけです。

この定義のスタック注釈は中括弧ではなく丸括弧を用いています。 それは、単なるコメントであって、名前付き入力引数や局所変数の定義ではないからです。 この定義は、名前付き入力引数や局所変数をひとつも使いません。 このことを完全に明確にするために、\を初めに置きました(半角空白をお忘れなく!)。 これで、この行はともかくコメントであるということが銘記されます。

この表は、捜されるべき角度の値が0から89の範囲になるように設計されています。 このようにして、角度の値そのものが、表における対応する正弦値への指標値ともなることができます。 ですから、(例えば、SIN:メソッドにおいて)正弦値を表から捜す段になると、 メッセージから引数として渡されてくる角度の値は、必要な正弦値に結びつけられた指標値として用いられることになります。 これがどのように働くのかはすぐにわかるでしょう。 しかし、これが46行目のスタック注釈で、各's演算に渡されるべき引数は正弦値と角度であるとしている理由なのです。 このとき、実際にはTO:セレクターは角度の数字をそのまま、 そのアレイ(わたしたちの表ですが)内の値への単なる指標値として見ているのです。

正弦値は、このとき、一続きの長い'sの列によって表に追加されますが、各々はまずは正弦値(かける10000) 、それに続いて二重の目的をもった指標/角度値というぐあいになっています。

スタック上で起ること

さて15から31行目のSIN:メソッドの定義に戻って、三つの異なる角度についてSIN:セレクターをSinesオブジェクトに送るときに、スタックに何が起るのかをみることにしましょう。 三つの角度とは、35度、180度、そして293度です。 下のリストでは、各演算に隣接する数字は、その実行の直後にスタック上にある実際の数値を意味しています。 ひとつより多いの数値がスタック上にあるときには、リストの一番初めの数値がスタックの最上位の値になります。 【少し行詰めして簡易化しました。":"はそこには到達しないこと、"---"はスタック上のアイテムがちょうどなくなったことを意味します。】

Statement 35° 180° 293°
degree 35 180 293
360 360 360 360
35 180 293
mod 35 180 293
dup 35 180 293
35 180 293
0< 0 0 0
35 180 293
IF 35 180 293
360 : : :
+ : : :
THEN 35 180 293
90 90 90 90
35 180 293
/mod 0 2 3
35 0 23
-> quadrant 35 0 23
-> degree --- --- ---
degree 35 0 23
NIF --- --- ---
quadrant : 2 :
at: axisVals : 0 :
ELSE --- : ---
quadrant 0 : 3
1 1 : 1
0 : 3
and 0 : 1
IF --- : ---
90 : : 90
degree : : 23
: : 90
- : : 67
ELSE --- : :
degree 35 : :
THEN 35 : 67
at: self 5736 : 9205
quadrant 0 : 3
5736 : 9205
2 2 : 2
0 : 3
5736 : 9205
AND 0 : 2
5736 : 9205
IF 5736 : 9205
negate : : -9205
THEN 5736 : -9205
THEN 5736 0 -9205
さて、それぞれの角度の場合に何が起っているのか説明しましょう。

18行目のMOD演算は、入力された角度を360で割った余りをスタックに提供します。 入力が360かそれより大きかったときには、角度の値を0から359までの間の数値に正規化します。入力が負であった場合には、MOD演算は-359と0の間の数値を返すので、 さらに正規化が必要です。19行目ではそれが負であったかどうかをテストし、もし負であったなら、360を加えて、等価な正の(0から359の範囲の正しい)角度に変換します。

20行目の/MOD演算は正規化された角度の値をスタックから取り除き、商と余りを返します。 商が0はそれが右上象限にあることを意味し、1は角度は左上の第二象限にあること意味し、等々、となります。 余りは正弦表に対して調べられる角度値になります。 表は、全360度領域のうちの90度分の切片についてしか、値を含んでいないからです。 21行目では、これらの値はスタックから取り除かれ、局所変数に格納されます。

22および23行目の次の演算のために、DEGREEから値を取り出し(しかし、これはDEGREEから値を取り除いてしまうわけではなく、スタックにコピーするだけです。)、それがゼロに等しいかどうかを調べます。

値がゼロなら、角度は90度の倍数ということになります。したがってこれは、二つの象限の境界線上にあります。 時間と計算を省くため、これら四つの境界のための正弦値はAxisValsアレイに格納してあります。 角度の値はゼロなので、23行目のNIFステートメント以降の演算が実行されます。 以前に保存してあった象限の値がスタックに置かれ、AT:セレクターの指標として利用されます。 AxisValsのクラスであるwArrayでのAT:メソッドは、 アレイに値を置くのに使われた格納演算TO:の反対にあたります。 AT:演算は、スタックのトップに置かれた指標値にしたがって、アレイオブジェクト(この場合はAxisValsという名前ですが)から値を取り出します。 180度の例では、値2がquadrantに保存されたので、それがスタックに置かれます。 指標2に対応するAxisValsの小包にある値が、今度はスタックに置かれます(値はアレイからコピーされるだけで、取り除かれません。)。 この時点で、最終的な正弦値がスタックにおかれるので、これ以上の演算操作は必要ありません。 入れ子のIF...ELSE...THENステートメントの規則に従って、 実行は一番外のTHENステートメントへと続き、ここでこのメソッドは終わりです。

しかし、角度の値がゼロでないときには、もっとずっと多くのことが起こります。 24行目で象限の値は1とANDされ、1か3であるどうか検証されます。 もしもそうであれば、DEGREEの値が取り出され、25行目でそこから90が引き算されます (正弦値は90度までは増加していき、それから180度までは鏡像対称に減少していきます。)。 そうでなければ、26行目で再びDEGREEの値がスタック上に置かれます。

28行目で、AT:セレクターは現在スタック上にある指標値をとり(これはたまたま、正弦表でチェックされるべき角度でもあります)、Sinesアレイから値を取り出します。 SELFは、自分自身に対して -- この場合Sinesオブジェクトですが -- 取り出し演算AT:を実行させるように、とMopsに告げています。

そのAT:取り出し演算は、表から正弦値を取り出しスタック上に置きます。 最後にあとひとつ仕事が残っています — その正弦値が正であるのか負であるのかを決めることです。 象限の数値は29行目で2とANDされます。 象限が2または3であれば、これは正弦値が負の象限ですが、このANDの結果は、 非ゼロになるでしょう。 この場合、まだスタックに唯一残っている正弦値は、(30行目のNEGATE演算で)負に変換されます。 そうでない場合は、正のままで、メソッドは終わります。

33および34行目のCOS:メソッドは、SIN:メソッドの力を借りますが、 これは単に角の正弦と余弦の間の数学的関係を勘案して修正しているに過ぎません。 余弦値は、正弦値から90度の位相遷移によって計算されます。【cos(θ) = sin(θ+90)】

プログラムのこの地点(66行目まで)においては、角度として与えられた数値の正弦値を計算するために送るべきメッセージは、 次のような形になります。
125 sin: Sines
これをさらに単純化するため、 二つのMops定義が追加されています(68-69行目)。 各ワードは上のようなメッセージを送ります。以後は、 プログラム内で角の正弦値を得るために必要なコードは、下のようなものだけになります。:
125 sin

71行目から76行目まで

クラスAngleは、68行目と69行目のSINおよびCOSのような、あるクラスのオブジェクトへのメッセージによって定義されているものを、それにもかかわらずそのクラスとは別のクラス定義で使うにはどのようにすれば良いのか、についての実例となっています。 このクラス、整数クラスは、二つのメソッド、SIN:とCOS:を持っています。 これらは外見上TrigTableのメソッドとメソッド名を持っています。 しかし、それらと干渉し合うことはありません。 なぜなら、Angleクラスのオブジェクトを生成したならば、そのオブジェクトはそれ自身のクラス階層においてのみ、 メソッドを捜すからです。 それはTrigTableクラスが存在しているということすら知りません。 Angleクラスにおけるメソッドが新しいMopsワードSINを利用するときには、 そのワードに命じてそれが為すべきことをメモリー内に捜させるのです。たとえそれが他のクラス内で作動することを意味している場合であっても — 全ては、Angleクラスの統合性を攪乱することなく、そしてTrigTableクラスの全装備を継承することもなく、行われるのです。

‘get: self’メッセージ(73及び74行目)は、Angleクラスより生成されるオブジェクトに格納された整数の値を引き出します。 そのオブジェクトに値を格納するには、Angleクラスのクラス階層を通覧する必要があるでしょう。そのスーパークラスIntに、値を格納するPUT:メソッドが見つかるでしょう。 例えば、次のようなオブジェクトを生成したとします。:
angle Narrow
すると、あなたはNarrowのメモリー領域に整数のための小包をとっておいたことになります。 というのは、クラスAngleはIntクラスのサブクラスだからです。 それからオブジェクトNarrowに値(30)を格納するには、 次のようなメッセージを送る必要があるでしょう:
30 put: Narrow
その後には、次のようなメッセージを送ることができます。:
sin: Narrow
これはAngleクラスのSIN:メソッドを作動させます。 値30が‘get: self’演算によって取り出され、 それからその正弦値がMopsワードSINによって計算されます。

Mopsにロードしてこれを自分で試してみてください。 ファイル"Sin"(‘Demo folder’にあります)を辞書にロードするには、 Mopsの(Fileメニューの)Load...メニューアイテムを使って下さい。 それから、Angleクラスのオブジェクトを生成してください。 そして、値をそのオブジェクトにPUT:し、その値の正弦値と余弦値を計算するメッセージを そのオブジェクトに送ってください。


チュートリアル目次へ
前へ < レッスン15 次へ > レッスン17



最終更新:2018年12月09日 14:58