この文書の現在のバージョンと選択したバージョンの差分を表示します。
次のリビジョン | 前のリビジョン 次のリビジョン 両方とも次のリビジョン | ||
ch_syntax [2018/01/04 06:00] kanemune 作成 |
ch_syntax [2020/07/11 05:09] klab [インスタンス変数] |
||
---|---|---|---|
ライン 1: | ライン 1: | ||
- | [[マニュアル]]に戻る。 | ||
- | |||
# ドリトル言語の基礎知識 | # ドリトル言語の基礎知識 | ||
ここでは、最初に「プログラミングとはどういうことか」ということを簡単に説明した後、ドリトル言語によるプログラムの基本的な概念と原理を説明する。 | ここでは、最初に「プログラミングとはどういうことか」ということを簡単に説明した後、ドリトル言語によるプログラムの基本的な概念と原理を説明する。 | ||
ライン 15: | ライン 13: | ||
* コンピュータは単なる命令を実行する装置だから、その命令を取り替えることによって、どのような作業でもこなすようにさせられる。 | * コンピュータは単なる命令を実行する装置だから、その命令を取り替えることによって、どのような作業でもこなすようにさせられる。 | ||
- | CENTER:&show(cb-computer.png,nolink,画像の説明,8%); | + | {{:pasted:20180103-210054.png?350}} |
そして、プログラミングとは「プログラムを作ること」であり、上の説明の延長でいえば、コンピュータに「自分がさせたいこと」を実行させるように、命令を並べて行く作業だ、ということになる。 | そして、プログラミングとは「プログラムを作ること」であり、上の説明の延長でいえば、コンピュータに「自分がさせたいこと」を実行させるように、命令を並べて行く作業だ、ということになる。 | ||
ライン 25: | ライン 23: | ||
プログラミング言語で書き表したものを実際に実行するためには、また別のソフトウェア(プログラミング言語処理系)を使う。プログラミング言語処理系には、プログラミング言語で書き表したものを機械語に変換する方式(コンパイラ)と、プログラミング言語で書き表したものを読み取りながら直接その動作を実行する方式(インタプリタ)とがある。 | プログラミング言語で書き表したものを実際に実行するためには、また別のソフトウェア(プログラミング言語処理系)を使う。プログラミング言語処理系には、プログラミング言語で書き表したものを機械語に変換する方式(コンパイラ)と、プログラミング言語で書き表したものを読み取りながら直接その動作を実行する方式(インタプリタ)とがある。 | ||
- | CENTER:&show(cb-interpreter.png,nolink,画像の説明,8%); | + | {{:pasted:20180103-210112.png?400}} |
ここまでは一般的な話だったが、次節以降では命令の内容や書き表し方としてドリトル言語の場合を学んで行くことにする。現在のドリトルのプログラミング言語処理系はインタプリタ方式を採用している。 | ここまでは一般的な話だったが、次節以降では命令の内容や書き表し方としてドリトル言語の場合を学んで行くことにする。現在のドリトルのプログラミング言語処理系はインタプリタ方式を採用している。 | ||
ライン 33: | ライン 31: | ||
一般にプログラムでは、さまざまな情報(データ)を取り扱う。ドリトルでは、これらを総称して**オブジェクト**(もの)と呼んでいる。我々が日常生活で接する「もの」はさまざまな大きさ、形、色、機能を持っているが、ドリトルのオブジェクトも同様である。ドリトルはコンピュータ上で動くプログラミング言語なので、これらの大きさ、色、機能なども、それらをプログラムで扱うとしたら、すべてコンピュータの上の情報として表すことになる…つまり、大きさ、色、機能などの情報もまたもとのオブジェクトに付随するオブジェクトだということになる。このような、オブジェクトに付随する情報をそのオブジェクトの**プロパティ**と呼ぶ。 | 一般にプログラムでは、さまざまな情報(データ)を取り扱う。ドリトルでは、これらを総称して**オブジェクト**(もの)と呼んでいる。我々が日常生活で接する「もの」はさまざまな大きさ、形、色、機能を持っているが、ドリトルのオブジェクトも同様である。ドリトルはコンピュータ上で動くプログラミング言語なので、これらの大きさ、色、機能なども、それらをプログラムで扱うとしたら、すべてコンピュータの上の情報として表すことになる…つまり、大きさ、色、機能などの情報もまたもとのオブジェクトに付随するオブジェクトだということになる。このような、オブジェクトに付随する情報をそのオブジェクトの**プロパティ**と呼ぶ。 | ||
- | CENTER:&show(cb-object.png,nolink,画像の説明,8%); | + | {{:pasted:20180103-210129.png?300}} |
このように、すべての情報をオブジェクトとして統一的に扱い、さまざまな機能もオブジェクトに付随しているという形で扱うプログラミング言語を**オブジェクト指向言語**という。今日のソフトウェア開発ではオブジェクト指向言語が多く使われる。C++、Javaなどはオブジェクト指向言語の例である。ドリトルもオブジェクト指向言語である。 | このように、すべての情報をオブジェクトとして統一的に扱い、さまざまな機能もオブジェクトに付随しているという形で扱うプログラミング言語を**オブジェクト指向言語**という。今日のソフトウェア開発ではオブジェクト指向言語が多く使われる。C++、Javaなどはオブジェクト指向言語の例である。ドリトルもオブジェクト指向言語である。 | ||
ライン 45: | ライン 43: | ||
</code> | </code> | ||
- | CENTER:&show(cb-variable.png,nolink,画像の説明,8%); | + | {{:pasted:20180103-210149.png?250}} |
変数は「いれもの」なので、プログラムの中でさまざまに内容(オブジェクト)を入れ換えることもできる。ある変数の内容を入れ換えないで、ずっと1つのオブジェクトを入れておく場合には、その変数の名前のことを、その「オブジェクトの名前」だと思っていても差し支えない。 | 変数は「いれもの」なので、プログラムの中でさまざまに内容(オブジェクト)を入れ換えることもできる。ある変数の内容を入れ換えないで、ずっと1つのオブジェクトを入れておく場合には、その変数の名前のことを、その「オブジェクトの名前」だと思っていても差し支えない。 | ||
ライン 74: | ライン 72: | ||
メッセージ送信によりオブジェクトのメソッドを呼び出すとき、必要に応じて追加の情報を渡すことができる。これをメソッド呼び出しの**パラメータ**と呼ぶ。ドリトルでは、パラメータはメソッド名の**前に**書くことになっている。 | メッセージ送信によりオブジェクトのメソッドを呼び出すとき、必要に応じて追加の情報を渡すことができる。これをメソッド呼び出しの**パラメータ**と呼ぶ。ドリトルでは、パラメータはメソッド名の**前に**書くことになっている。 | ||
- | CENTER:&show(cb-message.png,nolink,画像の説明,8%); | + | {{:pasted:20180103-210210.png?400}} |
たとえば、ボタンのメソッド「作る」には、パラメータとしてボタンに表示するラベルの**文字列**を渡すことができる。先のプログラムをそのように直してみる。 | たとえば、ボタンのメソッド「作る」には、パラメータとしてボタンに表示するラベルの**文字列**を渡すことができる。先のプログラムをそのように直してみる。 | ||
ライン 92: | ライン 90: | ||
上の例のように、メソッドのパラメータは複数個指定してもよい。では、並んでいるものがメソッドの名前なのかパラメータなのかはどうやって分かるのだろうか? 実は、「!」の右側ではすべての名前はメソッド名として扱われる。「" "」で囲まれた文字列や、「100」などの数値はメソッド名ではないのでパラメータになる。変数名を指定したいときは、変数名を「()」で囲んで「(x)」などのように指定する(後の節で詳しく説明する)。 | 上の例のように、メソッドのパラメータは複数個指定してもよい。では、並んでいるものがメソッドの名前なのかパラメータなのかはどうやって分かるのだろうか? 実は、「!」の右側ではすべての名前はメソッド名として扱われる。「" "」で囲まれた文字列や、「100」などの数値はメソッド名ではないのでパラメータになる。変数名を指定したいときは、変数名を「()」で囲んで「(x)」などのように指定する(後の節で詳しく説明する)。 | ||
- | CENTER:&show(cb-cascade.png,nolink,画像の説明,8%); | + | {{:pasted:20180103-210229.png?400}} |
メッセージのカスケードがある場合、変数に格納される値(メッセージ送信式全体の値)は、一番最後のメソッドが返した値になる。上のプログラムの場合、メソッド「位置」はボタンの位置を変更した後、そのボタンオブジェクト自体を返すので、変数「ボタン1」に格納される値は先のプログラムと同じである。 | メッセージのカスケードがある場合、変数に格納される値(メッセージ送信式全体の値)は、一番最後のメソッドが返した値になる。上のプログラムの場合、メソッド「位置」はボタンの位置を変更した後、そのボタンオブジェクト自体を返すので、変数「ボタン1」に格納される値は先のプログラムと同じである。 | ||
ライン 105: | ライン 103: | ||
ドリトルでは1つの式は全体としてメッセージ送信記法であるか、全体として中置記法であるかのどちらかであるが、「(…)」で囲まれた中は外側とは別にメッセージ送信記法か中置記法かを選ぶことができる。メッセージ送信記法か中置記法かは、「!」の有無で判断できる。 | ドリトルでは1つの式は全体としてメッセージ送信記法であるか、全体として中置記法であるかのどちらかであるが、「(…)」で囲まれた中は外側とは別にメッセージ送信記法か中置記法かを選ぶことができる。メッセージ送信記法か中置記法かは、「!」の有無で判断できる。 | ||
- | CENTER:&show(cb-infix.png,nolink,画像の説明,30%); | + | {{:pasted:20180103-210245.png?400}} |
中置記法とメッセージ送信記法のもう1つの違いは、中置記法の中では名前は変数を表す、ということである。これに対し、メッセージ送信記法の中では直接変数を書けるのは「!」の左側だけであり、「!」の右側では名前はメソッド名として扱われる。したがって、パラメータなどで変数を指定したい場合は「(…)」で囲む必要がある(囲んだ中は中置記法にできるため)。たとえば、中置記法の「x+y」をメッセージ送信記法で書くと「x!(y)足す」になるが、この「(y)」は丸かっこの中に(「!」がないため)中置記法が書かれているものとして扱われている。 | 中置記法とメッセージ送信記法のもう1つの違いは、中置記法の中では名前は変数を表す、ということである。これに対し、メッセージ送信記法の中では直接変数を書けるのは「!」の左側だけであり、「!」の右側では名前はメソッド名として扱われる。したがって、パラメータなどで変数を指定したい場合は「(…)」で囲む必要がある(囲んだ中は中置記法にできるため)。たとえば、中置記法の「x+y」をメッセージ送信記法で書くと「x!(y)足す」になるが、この「(y)」は丸かっこの中に(「!」がないため)中置記法が書かれているものとして扱われている。 | ||
ライン 150: | ライン 148: | ||
「!」の前に何もないときは、そのメソッドを持っているオブジェクトが指定されているものとして扱われる。また、特別な名前「自分」もメソッドを持っているオブジェクトを指定するのに使うことができる。従って上の例は「自分!…」のように書いてもよい。 | 「!」の前に何もないときは、そのメソッドを持っているオブジェクトが指定されているものとして扱われる。また、特別な名前「自分」もメソッドを持っているオブジェクトを指定するのに使うことができる。従って上の例は「自分!…」のように書いてもよい。 | ||
- | CENTER:&show(cb-blockparams.png,nolink,画像の説明,8%); | + | {{:pasted:20180103-210342.png?500}} |
ブロックは1つの式であり、最後に評価した式の値をブロック全体の値として返す。メソッドから値を返したいときはこれを利用する。上の例では、最後に評価されるのはメソッド「歩く」なので、それが返した値、つまりかめた自身が「曲がって動く」の返す値となる。そこで引き続きかめたに対するメソッド「横の位置?」を呼び出してそのX座標を調べているわけである。 | ブロックは1つの式であり、最後に評価した式の値をブロック全体の値として返す。メソッドから値を返したいときはこれを利用する。上の例では、最後に評価されるのはメソッド「歩く」なので、それが返した値、つまりかめた自身が「曲がって動く」の返す値となる。そこで引き続きかめたに対するメソッド「横の位置?」を呼び出してそのX座標を調べているわけである。 | ||
ライン 165: | ライン 163: | ||
</code> | </code> | ||
- | CENTER:&show(cb-times.png,nolink,画像の説明,8%); | + | {{:pasted:20180103-210401.png?250}} |
次のプログラムを実行すると、初期値が0の変数「a」に1を加える処理を10回行い、結果として画面に10が表示される。 | 次のプログラムを実行すると、初期値が0の変数「a」に1を加える処理を10回行い、結果として画面に10が表示される。 | ||
ライン 194: | ライン 192: | ||
</code> | </code> | ||
- | CENTER:&show(cb-while.png,nolink,画像の説明,8%); | + | {{:pasted:20180103-210421.png?200}} |
たとえば、100以上の値を持つ最初のフィボナッチ数を表示させるプログラムは次のようになる。 | たとえば、100以上の値を持つ最初のフィボナッチ数を表示させるプログラムは次のようになる。 | ||
ライン 215: | ライン 213: | ||
いずれも、1番目のブロックを実行した結果が真であれば2番目のブロックが実行される。さらに下の形では、2番目のブロックが実行されなかった場合は3番目のブロックが実行される。メソッド「なら」や「そうでなければ」はこれらの制御を適宜行うためのオブジェクトを返す。 | いずれも、1番目のブロックを実行した結果が真であれば2番目のブロックが実行される。さらに下の形では、2番目のブロックが実行されなかった場合は3番目のブロックが実行される。メソッド「なら」や「そうでなければ」はこれらの制御を適宜行うためのオブジェクトを返す。 | ||
- | CENTER:&show(cb-if.png,nolink,画像の説明,8%); | + | {{:pasted:20180103-210442.png?550}} |
次のプログラムを実行すると、最初に1から10までの乱数を発生し、変数「数」に入れる。続いて、「数」が5より大きいかを判定し、真のときは「なら」に続くブロックを実行し、偽のときは「そうでなければ」に続くブロックを実行する。結果として、実行するたびに、画面に「大きい」と「小さい」がランダムに表示される。 | 次のプログラムを実行すると、最初に1から10までの乱数を発生し、変数「数」に入れる。続いて、「数」が5より大きいかを判定し、真のときは「なら」に続くブロックを実行し、偽のときは「そうでなければ」に続くブロックを実行する。結果として、実行するたびに、画面に「大きい」と「小さい」がランダムに表示される。 | ||
ライン 239: | ライン 237: | ||
</code> | </code> | ||
- | CENTER:&show(cb-ifelseif.png,nolink,画像の説明,8%); | + | {{:pasted:20180103-210502.png?300}} |
ライン 249: | ライン 247: | ||
タイマーは、あらかじめ指定された**間隔**で、指定された**回数**または**時間**だけ、ブロックを繰り返して実行する。標準では、間隔が0.1秒、回数が100回に設定されている。 | タイマーは、あらかじめ指定された**間隔**で、指定された**回数**または**時間**だけ、ブロックを繰り返して実行する。標準では、間隔が0.1秒、回数が100回に設定されている。 | ||
- | CENTER:&show(cb-timer.png,nolink,画像の説明,8%); | + | {{:pasted:20180103-210522.png?350}} |
ブロックを指定してタイマーのメソッド**実行**を呼び出すと、タイマーはパラメータとして受け取ったブロックを設定された時間間隔で繰り返し実行する。最初の実行は、指定された間隔だけ待った後に行われる。 | ブロックを指定してタイマーのメソッド**実行**を呼び出すと、タイマーはパラメータとして受け取ったブロックを設定された時間間隔で繰り返し実行する。最初の実行は、指定された間隔だけ待った後に行われる。 | ||
ライン 347: | ライン 345: | ||
</code> | </code> | ||
- | CENTER:&show(cb-array1.png,nolink,画像の説明,4%); | + | {{:pasted:20180103-210551.png?150}} |
配列に入っている要素の数は、**要素数?**で調べることができる。次のプログラムでは、配列に3個の数値を入れた後で、要素数を画面に表示している。画面には3が表示される。 | 配列に入っている要素の数は、**要素数?**で調べることができる。次のプログラムでは、配列に3個の数値を入れた後で、要素数を画面に表示している。画面には3が表示される。 | ||
ライン 359: | ライン 357: | ||
**書く**を使うと、配列の末尾に新しい要素を追加することができる(要素数は1多くなる)。また、**上書き**を使うと、配列の指定位置の要素を書き換えることができる(要素数は変わらない)。**消す**を使うとオブジェクトを指定して、**位置で消す**を使うと要素の位置を指定して、要素を削除することができる。 | **書く**を使うと、配列の末尾に新しい要素を追加することができる(要素数は1多くなる)。また、**上書き**を使うと、配列の指定位置の要素を書き換えることができる(要素数は変わらない)。**消す**を使うとオブジェクトを指定して、**位置で消す**を使うと要素の位置を指定して、要素を削除することができる。 | ||
- | CENTER:&show(cb-array2.png,nolink,画像の説明,8%); | + | {{:pasted:20180103-210606.png?250}} |
次のプログラムでは、3つの要素が格納された配列の末尾に要素を追加し、3番目の要素を上書きした後、2番目の要素を削除し、要素数を画面に表示している。画面には3が表示される。 | 次のプログラムでは、3つの要素が格納された配列の末尾に要素を追加し、3番目の要素を上書きした後、2番目の要素を削除し、要素数を画面に表示している。画面には3が表示される。 | ||
ライン 387: | ライン 385: | ||
</code> | </code> | ||
- | CENTER:&show(cb-array3.png,nolink,画像の説明,8%); | + | {{:pasted:20180103-210625.png?500}} |
ライン 404: | ライン 402: | ||
</code> | </code> | ||
- | CENTER:&show(cb-prototype.png,nolink,画像の説明,8%); | + | {{:pasted:20180103-210642.png?400}} |
子のオブジェクトは親のオブジェクトが持っていたプロパティ(値やメソッド定義)をすべてそのまま引き継ぎ、親と同じように扱うことができる。この仕組みを利用して、タートル、ボタン、配列など、さまざまな標準オブジェクトをプロトタイプとして持つオブジェクトを必要なだけ作って利用できるわけである。 | 子のオブジェクトは親のオブジェクトが持っていたプロパティ(値やメソッド定義)をすべてそのまま引き継ぎ、親と同じように扱うことができる。この仕組みを利用して、タートル、ボタン、配列など、さまざまな標準オブジェクトをプロトタイプとして持つオブジェクトを必要なだけ作って利用できるわけである。 | ||
ライン 420: | ライン 418: | ||
</code> | </code> | ||
- | CENTER:&show(cb-lookup.png,nolink,画像の説明,8%); | + | {{:pasted:20180103-210705.png?400}} |
ただし、上で説明したように、子のオブジェクトに同じ名前のプロパティが見つかった場合はそちらが使われるので、親の同名のプロパティは参照されなくなる。たとえば、次の場合はObjBのプロパティが参照されるので、「180」が表示される。 | ただし、上で説明したように、子のオブジェクトに同じ名前のプロパティが見つかった場合はそちらが使われるので、親の同名のプロパティは参照されなくなる。たとえば、次の場合はObjBのプロパティが参照されるので、「180」が表示される。 | ||
ライン 450: | ライン 448: | ||
### インスタンス変数 | ### インスタンス変数 | ||
- | **インスタンス変数**とは、個々のオブジェクトに付随する情報を保持するための変数のことをいう。ドリトルでは、インスタンス変数は個々のオブジェクトのプロパティに他ならない。ブロックがオブジェクトのプロパティとして格納されていて、メソッドとして呼び出された場合、そのブロックの中の変数で、「{\tt |…|}の中に書かれているパラメータやローカル変数以外のものは、インスタンス変数を意味している。たとえば次の例では、{\tt ObjB:x}が21増やされて221になり、それが表示される。 | + | **インスタンス変数**とは、個々のオブジェクトに付随する情報を保持するための変数のことをいう。ドリトルでは、インスタンス変数は個々のオブジェクトのプロパティに他ならない。ブロックがオブジェクトのプロパティとして格納されていて、メソッドとして呼び出された場合、そのブロックの中の変数で、「|…|」の中に書かれているパラメータやローカル変数以外のものは、インスタンス変数を意味している。たとえば次の例では、ObjB:xが21増やされて221になり、それが表示される。 |
<code> | <code> | ||
ObjB=ボタン!作る。 | ObjB=ボタン!作る。 |