復習のページ
ここからの続き…
■新しいオブジェクトの設計のしかた
- 新しいオブジェクトを作る前に、まず、その設計図・仕様書を作る。
- 設計図・仕様書には、そのオブジェクトがどういった刺激に反応するか、関連するオブジェクトをなんという名札に繋ぎとめておけるかを記述しておく。
- 設計図・仕様書を新しく作るには、システムブラウザの上の段、左端の枠(クラスカテゴリ枠)の黄ボタンメニューの「add item...」で新しいカテゴリを追加し、そのとき現れるテンプレートの #NameOfSubclass の「NameOfSubclass」部分を書き換えて accept する。
- 関連するオブジェクトをどんな名札に繋ぎとめておくかは同じ画面の「instanceVariableNames: ''」 の項の ' ' 内にスペースで区切って名札の名前を記述して accept する。
- どういった刺激に反応するかについては、システムブラウザの上の段、左から3番目の枠(メソッドカテゴリ枠)にある「no messages」もしくは「as yet unclassified」クリックしたときに現れるテンプレートに従って、刺激の名前と、その刺激を受けたときに何をするかを記述する。
- 設計図・仕様書は「クラス」という。
- 名札は「変数」という。
サクサク向け補足
以上はよろしいでしょうか。--sumim - 2002-07-08, 22:01:06
大丈夫です。
メッセージ==刺激については読み替えできています。
このあたりは逆に言えば「ブラウザの使用法」ということも含め、割り切って受け止めています。以前よく注意されましたが好き勝手やれるのが感動的でしたね。(ノーティファイア出しながら……)
名札については重点的に教えていただいたもので、風船の先についた名札(壁越し)の絵でほぼ理解できたと思います。
問題はここから先。
具体的な刺激(メッセージ)の送り方受け方の部分です。
設計図・仕様書をいろいろ変更してきました。
ifTrueでの好意対象初期値セットの式までは間違いが多いながら頭で考えられました。なのにここから先は……。
まず、言い方が正しくありませんがDOSで言えばコマンドとそのオプションがわかりません。前にごく簡単な説明だけで出てきたaString(文字列として返す?)やaStream(繋げた文字列を返す?)、valueとvalue:(前回教えていただきました)といった部分……サクサクで言えばクロスライブラリィがわかりません。
DOSやUNIXコマンドのプレファレンスくらいしか馴染みがないので「このコマンドは値をどう返す」「何をするためのコマンド」とか、そういう図式でないとうまく理解できないようです。
Smalltalkは本体に全て書いてあるそれ(クロスライブラリィ)を読み解いて行くことで理解し習得できる!
素晴らしいですが、それを読み解く「取っ掛かり」の部分がまだ理解度不十分です。--さ茂 - 2002-07-09, 06:47:04
>DOSで言えばコマンドとそのオプションがわかりません
ifTure: や、select: で言えば、ifTrue: や select: が“コマンド”でそれに伴わせる [ ^ nil ] や、[ :ある人間 | ある人間 の名前 = ある名前 ] が“そのオプション”といったところでしょうか。ついでに「オブジェクト メッセージ1 メッセージ2」と記述するのはいわゆる“パイプ”ですね。--sumim - 2002-07-09, 11:27:37
■オブジェクトの生み出し方とその寿命
- オブジェクトは原則として「設計図・仕様書の名称 new」を do-it などすることで生み出すことができる。
- オブジェクトは何らかの名札に繋ぎとめておかなければ瞬殺されてしまう。
- オブジェクトは複数の名札に繋げることができる。
- オブジェクトに名札を繋げるには「名札 _ メッセージ式など」とする。
ここは大丈夫ということでしたね。
■オブジェクトへのメッセージの与え方とその反応の返し方、返り方
- 「オブジェクト メッセージ」と記述。これをメッセージ式と言う。
- オブジェクトはメッセージを受け取ると、そのメッセージにどう対処するかを記載した仕様書に記述された一連のメッセージ式を実行する。
- 仕様書は次のように記述する。
メッセージ名 または メッセージ名: そのオプションとして与えられたオブジェクトを繋ぎとめるための変数
"このメッセージを受け取ったときにどんなことが起こるのか、何を返すのかを記述したコメント"
| テンポラリ変数1 テンポラリ変数2 |
メッセージ式1.
メッセージ式2.
メッセージ式3.
^ 返すオブジェクト
- オプション付きのメッセージの例外として、算術記号やそれに準ずるもの、たとえば「+」や「/」などをメッセージ名に使う場合はメッセージ名にコロン「:」は不要で「+:」などとしてはいけない。
- オプションを複数与えたいときは「パート1: オプション1 パート2: オプション2」のようにオプションの数だけコロン「:」を付けたメッセージの名前を作り、各々のコロンの後にオプションとして与えられたオブジェクトを繋ぎとめておくための変数を用意する。
- メッセージ名はメッセージ式として記述したときに、文章のようになるように、またどんな反応が返るのかがわかりやすいものを作る、選ぶ。また、すでに同種の反応を返すメッセージが別のオブジェクトで定義されているときはできるだけそれと同じものを使う。
- 複数の連続したメッセージ式はピリオド「.」によって区切られる。
- 最後の「^ 返すオブジェクト」が明示されていないときは、メッセージを受けたオブジェクト自身が反応として返る。
- 「^」はそこで作業を中断して続くオブジェクト(もしくはメッセージ式で返されるオブジェクト)をそのメッセージの反応として返すときに使う。その後にメッセージ式があっても無視される。
- 「オブジェクトA メッセージ1 メッセージ2」と記述した場合は、「オブジェクトA メッセージ1」の反応として返ってきたオブジェクトBに「オブジェクトB メッセージ2」式を実行するのと同じ。
- 「オブジェクトA メッセージ1; メッセージ2」とメッセージ間にセミコロン「;」を挿入したときは、「オブジェクトA メッセージ1. オブジェクトA メッセージ2」と同じ。
ここまでよろしいでしょうか?--sumim - 2002-07-09, 11:41:22
どんどんわかってきたような気がするのは……錯覚でしょうか? <そうでしょう(^-^;)
>ifTure: や、select: で言えば、ifTrue: や select: が“コマンド”で
あえてコマンド・オプションにたとえていただきありがとうございます。本当はこういう読み替えはSmalltalkではNGだと思います。Smalltalkの言葉ですべて認識できるよう努力していきます。
>「^」はそこで作業を中断して続くオブジェクト
過去の例題に対する自分の答えを見て、↑ここがまだ不十分だと気づきました。
「中断して実行」という部分だけ抜き出して憶え、単純に図式的に用いていますがこれの本当の仕組みがまだ曖昧のようです。
なぜ「最後なのに中断させて」「オブジェクトをメッセージの反応として返す」のか?
瞳
"瞳の色を答える"
^ '青'
という極初期の例題に戻ってみますと、これは
変数 瞳 Print-it '青'
と反応が返ります。変数にはこの段階でロランというグローバル変数しかないので、
ロラン 瞳 Print-it '青'
となりました。
ロランという変数に"瞳"という刺激を与えると、'青'というテキスト列(オブジェクト?)が表示されます。
話が行ったり来たりしますが、この'文字列'は仕組みはわかりませんがprint-itで自身を返します。
最近の例では、∀の人間class>>が嫌いな人
が嫌いな人
^ 憎悪対象
これで、憎悪対象単体をprint-itすると、憎悪対象は知らない変数ですとメッセージが出ます。
憎悪対象というオブジェクトはinstanceVariableです。インスタンスにあらかじめ登録された変数です。print-itで反応を返せないのは、インスタンス変数が該当するインスタンスの設計図・仕様書からしか参照されない(該当インスタンスのメソドしか使用できない)からなのですよね?
こう考えると、print-itで自身を返すオブジェクト'文字列'と他のオブジェクトの違いというのがまだ曖昧です。
print-itという操作(?)が「式の評価の一手法」(メッセージの送受信とその結果返される値の表示?)であること以外あまり理解していないということも重大かと思います。--さ茂 - 2002-07-09, 20:41:10
>なぜ「最後なのに中断させて」「オブジェクトをメッセージの反応として返す」のか?
最後だろうと途中だろうと中断して返すのですが、中断すれば当然、それ以降のメッセージ式は無視されるのでそれを記述すること自体無意味となります。逆に ^ 云々の記述に意味を持たせるためには、必然的に最後に置くことになります。「中断させて」というのが活きるのは、ifTrue: などの刺激に伴わせたブロックに ^ 云々 という記述を含めたときです。単純に ^ 云々 という記述を含まないブロックを伴わせた場合は、続くメッセージ式が評価されます。しかし、ブロック内、換言して必然的にブロックに記述されたメッセージ式の最後に ^ 云々 という記述があれば、そこで中断して「云々」に当たるオブジェクトを返して終わりになります。
| ある数字 | ある数字 _ 1. ある数字 = 1 ifTrue: ['ブロック内です']. '私が最後です'
| ある数字 | ある数字 _ 1. ある数字 = 1 ifTrue: [^ 'ブロック内です']. '私が最後です'
前者について。変数「ある数字」には 1 が繋がっているので「= 1」というメッセージに対しては true を返します。true に対して「ifTrue: ['ブロック内です']」というメッセージを送ると、ブロック内の記述を評価します。これは「ブロック内です」という文字列オブジェクトを生み出すための記述ですが、生み出されたオブジェクトはどこにも繋がっていないので瞬殺(無視)されます。続く、「'私が最後です'」という記述が評価されて、これが最後の式になるので、一連のコードの print-it の結果は「'私が最後です'」になります。
後者について。変数「ある数字」には 1 が繋がっているので「= 1」というメッセージに対しては true を返します。ここまでは一緒です。true に対して「ifTrue: [ ^ 'ブロック内です']」というメッセージを送ると、ブロック内の記述を評価します。これは「ブロック内です」という文字列オブジェクトを生み出すための記述ですが、^ が付いているので、ここで作業を中断して ^ 直後の記述の結果を返します。したがって、一連のコードの print-it の結果は「'ブロック内です'」になります。最後の「'私が最後です'」という記述は記述自体が無視されます。--sumim - 2002-07-09, 21:12:27
■オブジェクトの参照方法、表記方法
- 基本的に、前述の方法で生まれたオブジェクトを直接、表記・参照する手段はない。いくつかの例外を除いて、オブジェクトは原則「名無し」である。
- オブジェクトにメッセージを送るためには、
- 他のメッセージ式の反応結果として生まれたオブジェクトに「オブジェクトA メッセージ1 メッセージ2」の書式のメッセージ2の要領で、生まれたオブジェクトに対して即座にメッセージを送信する、もしくは
- 利用できる変数に繋ぎとめてから「変数 メッセージ」といった記述をする必要がある。
- 便宜上の例外として、そのものを記述できるオブジェクトがある(サクサクではリテラル)
- nil, true, false
- 数値
- '文字列'
- $字
- #シンボル(文字列のようなオブジェクトだが、同一文字列なら同一のオブジェクトを参照する)
- 同様に便宜上の例外として後述のクラス(実はオブジェクト)も登録と同時にグローバル変数(同後述)に繋がるような仕組みになっているので、その名称の記述がすなわちそのものを表わすことになる。
■変数の利用可能範囲など
- 変数は利用可能範囲によっていくつか種類がある
- グローバル変数 …… どこでも使える。繋げられるオブジェクトはひとつだけ。Smalltalk at: #グローバル変数名 put: nil で宣言する。宣言せずに使用しようとしたときに現れるメニューでグローバル変数にするか指示することもできる。
- テンポラリ変数 …… ひとつのメッセージ仕様書内、もしくは do-it (print-it) する連続するメッセージ式の中でだけで使える。最初に | | で括って宣言する必要がある。繋げられるオブジェクトはひとつだけ。宣言せずに使用しようとしたときに現れるメニューでテンポラリ変数にするか指示することもできる。使用後に消滅する。
- インスタンス変数 …… ひとつのクラスの中のすべてのメッセージ仕様書内で使える。繋げられるオブジェクトはひとつだが、インスタンス(オブジェクト)ごとに別のものにできる。オブジェクトの設計の際、「instanceVariableNames: ''」 の項の ' ' 内にスペースで区切って宣言する。
- 他に、
- ワークスペースでのみ使用できるワークスペース変数
- 同じクラスのインスタンスで共有(ひとつだけオブジェクトを繋げておける)クラス変数
- 複数のクラスのインスタンスで共有できるプール変数
- インスタンスとしてのクラス(後述)が持つ、クラスインスタンス変数、があるが説明はまだ。
- 変数の仲間に、代入はできないが参照はできる偽変数というのがある。
- self 。メッセージ仕様書内で用い、メッセージを受け取ったオブジェクトが繋がっている。
- super 。self と同じだが、メッセージを送ったときの挙動が異なる。後述。
- 仕様書でメッセージがオプションを持つときに、そのオプションを表わすオプション名(前述の「そのオプションとして与えられたオブジェクトを繋ぎとめるための変数」)。
さ茂さん苦手の「後述…」が多いですが、ここまでいかがでしょう。--sumim - 2002-07-09, 21:47:52
>そのものを記述できるオブジェクトがある(サクサクではリテラル)
すっかり失念しておりましたがサクサクを読み返し確認しましたm(_ _)m。
>Smalltalk at: #グローバル変数名 put: nil で宣言する。
サクサクで見かけて?だったat:put:が出てきました(^-^;)。
これはコレクションの要素を取り出すat:、その要素に値を挿入するput:、ということで配列?Arrayを操作する刺激だと曖昧に憶えていたのですが……。
この式ではSmalltalkで管理されるグローバル変数のArray(以前注意を受けたあのindex状のグローバル変数リスト?)からグローバル変数を取り出して(無いはずの新しい変数=新規作成?)、それにnilという値を挿入しているように見えます。
>さ茂さん苦手の「後述…」が多いですが、ここまでいかがでしょう。
まだ説明の無いものはほとんどサクサクだけでは理解不能なものです(^-^;)。--さ茂 - 2002-07-10, 21:59:17
…で、「後述」以外のものは大丈夫ですね? 復習の(そうです。これは復習なのです! at:put: なんて新しいものは無視してください!(笑))先を進めてよろしいですか? と、くどくどと申しますのも経験からこういうパターン(後述、もしくは、まだ説明を加えていない項目にこだわられるわりに、本質や本題についてコメントをいただけない状態)の時、きまって、後で「理解できていないからもう一度」コールをいただくように思います(^_^;)。--sumim - 2002-07-10, 22:06:30
■クラスもオブジェクト
- 設計図・仕様書であるクラスも実はオブジェクトである。
- つまり、クラス自身もその設計図・仕様書を持つ。
- これをメタクラスと呼び、「クラスの名前 class」と表記する。
- 実用上、これを参照するために表記するときも「クラスの名前 class」とする。
- オブジェクトを生み出すときに用いられる「クラス名 new」も、new というメッセージを送り、その結果、クラスのインスタンスが返ると考える。
- クラスを作るときに、使う下のテンプレートも、Object というクラスに subclass:instanceVariableNames:classVariableNames:poolDictionaries:category: という長いひとつのメッセージを送ることで実行されると考える。ちなみに、Smalltalk のコードの記述では改行による断絶は無視される。複数のメッセージ式の区切りはあくまでピリオドで、メッセージを再送信する場合もセミコロン「;」を用いるのは前述の通り。
Object subclass: #NameOfSubclass
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: ''
- 「あるクラス」に送るメッセージの仕様書は「あるクラス class」に記述する。
- システムブラウザでは上の段、左から2番目にある枠(クラス枠)の下に用意された instance、?、class のうち、class ボタンをクリックして切り換えると、そのクラスのメタクラスへの仕様(送られたメッセージにどう対処するか)の記述ができる。
■スーパークラスとサブクラス
- クラス間にはスーパー、サブの上下関係を作ることができる。
- サブクラスのインスタンスは、スーパークラスで定義された設計や仕様に従う。つまりスーパークラスに定義されたインスタンス変数を持ち、定義されたメッセージに反応することができる。
- サブクラスで同じ名前のメッセージへの振る舞いを重複定義した場合、サブクラスのそれが採用され、スーパークラスのそれは無視される。ただ、無視しないような仕組みも作ることができる。が、これはまだ説明の途中。→ self の代わりに super を使う。
- 前述の Object subclass: #新しいクラス ... のテンプレートに従った場合は、新しいクラスは Object のサブクラスとして作られる。あるクラスのサブクラスとして新しいクラスを作りたいときは「あるクラス subclass: #新しいクラス ...」とする。
- ここでの「スーパークラス」「サブクラス」の使い方は実はちょっと正しくありません。注目しているクラスがあって、それを基準に上に位置するなら「スーパークラス」、下にあるなら「サブクラス」と言い表すのが普通です。
ここまでよろしいでしょうか。--sumim - 2002-07-10, 22:24:41
「刺激」と「メッセージ」は、どちらを使ったらよろしいでしょうか? さ茂さんがメッセージを使われるようになってからメッセージに切り換えたのですが、刺激という表現も引き続き使っておられるようなので、できたら表記を統一したいと思います。--sumim - 2002-07-10, 22:43:39
ちなみに、at:put: はあくまで at:put: でひとつのメッセージ名で、at: と put: という2つのメッセージの合成ではありません(意味はそうなのですが…(^_^;))。同種のもので、value と value: があります。value: はコロンまでを含めてひとつのメッセージ名で、value にオプションを付けるために「:」を追加したものではなく(存在理由はそうなのですが…くどい!(笑))、value: というひとつの独立したメッセージ名で、value とは別物で区別されます。--sumim - 2002-07-10, 23:02:51
- これが、既存の環境(先の例ではDOSのコマンドとオプション)に見た目は意識して似せてはいるけど、それになぞらえて語ってしまうとおかしなことになる(「オブジェクト メッセージ」で全てを表現できる美しさが損なわれる)例の一つで、そうした置き換えを私が嫌う理由のひとつでもあります。
ふと、気が付けばここまでが今までの復習を流れとともに端的にまとめたものになります。サクサクを意識してまだ説明していないものものもいくつか取り上げましたが、それらを無視して、上記で怪しいな…という点がありましたらこの機会に遠慮なく尋ねていただき、クリアにしておくのがよいと思います。--sumim - 2002-07-10, 23:09:06
たとえば(言及されている対象自体は、ここではさらっと流しておいていただきたい at:put: についてなので蒸し返したくないのですが…(^_^;))「nilという値を挿入」もしくは別の場所での「憎悪対象というオブジェクト」などといった表現を用いておられるのを見るにつけ、まだ、変数とそれに対するオブジェクトの繋ぎとめ(名札と風船)の関係やそれに類するものへのご納得がいまいちで、何か箱のようなものに入れる、もしくは変数そのものがオブジェクトに成り代わるかのような印象を持っておられるように思いますがいかがでしょう。--sumim - 2002-07-10, 23:11:43
蒸し返しついでに、Array とその仲間たちについては、人間関係を複雑にする細工をするときに改めてご説明申し上げるつもりでおります。だいぶおしまいも見えてきたので今後の予定も一挙に公開(笑)しておきましょう。
- サブクラスでメッセージに対する振る舞いの重複定義があってもスーパークラスのそれを無視させない手だて。super の利用。
- 複雑な人間関係に対応できるようにする。Array の仲間の紹介とその利用。
- オブジェクト間の無線通信(直接対象を定めてメッセージを送らずに、関連オブジェクトに何かをさせる)。
- 改めて、執筆環境チェンジセットの解説(もちろん私ではなく、さ茂さんご自身による…です(^_^;))とその改造や拡張を愉しむ。
という具合に繋げていこうと思っています。もちろん、面白そうなことがあれば積極的に脱線するつもりです(笑)。--sumim - 2002-07-10, 23:20:19
>経験からこういうパターン(後述、もしくは、まだ説明を加えていない項目にこだわられるわりに、本質や本題についてコメントをいただけない状態)の時、きまって、後で「理解できていないからもう一度」コールをいただくように思います(^_^;)。
あぁバレてますm(_ _)m。まさに今その状態です。
ふいに新しいものが説明なく出てくると、トゲのように気になってしまいそれ以外の部分の考察・理解がおろそかになります。
もっともっと曖昧な部分があるのに、目が真新しい「先」のものに行ってしまいます。
今回はそうならないようにがんばっております。ですから少々もたつきますのでご容赦ください。
>「刺激」と「メッセージ」は、どちらを使ったらよろしいでしょうか?
わたし自身まだ決まっていないようです。刺激という言い方の方が長い付き合いなもので(^-^;)。「メッセージを送る」という言い方がちょっと具体的でないと思うと「刺激を与える」としちゃうようです。
できるかぎりメッセージを使うようにします。
では一旦、戻ります。--さ茂@AirH" - 2002-07-11, 12:58:32
>目が真新しい「先」のものに行ってしまいます。
このご性向がゆえに Squeak に着目していただけたわけですから、善し悪しですね(笑)。
>少々もたつきます
ここは私のほうのことはいっさいお気になさらず、基本的な部分も含めてひっかかっておられるところをじっくりと修めてください。やはりこうしたものは物語と同じように石を積み上げてゆくようなところもあり、下がぐらついていたり端折ったりするとせっかく時間をかけて形を作っても些細なことで一気に崩壊しかねないというきらいがあります。矛盾やこじつけの目立つ多くのシステムと違って、Smalltalk は自身が比類のない美しい調和で成立っているので、とことん突き詰めてもある程度は大丈夫だと思います(私の知識や表現力が十分でなく、ご納得のゆく説明やたとえ話ができないこともあるやも知れませんが(^_^;))。慣れ親しんでおられる他のシステムとの類似性で理解するのもひとつの手ではありますが、できたら さ茂さんなりの独立した「 Smalltalk ワールドとその価値観や概念」を頭の中にゆっくりでいいのでしっかりと築いていただくのが結局は早道かと存じます。--sumim - 2002-07-11, 14:31:13
>具体的でないと思うと「刺激を与える」としちゃう
では、どちらか一方には決めず、それぞれを私なりにふさわしいと思うときに使い分けることにします。差し障りがあれば、適宜、読み替えてください。--sumim - 2002-07-11, 15:06:20
ご無沙汰しておりました。
自習しながら悶々としておりましたが、掲示板>http://www.bbs-express.com/member04/sr_bbss.cgi?27shigerusでKYさんというSqueak仲間(^-^;)からいろいろアドバイスをいただいて徐々に不理解部分の洗い出しが出来てきました。
で、今夜から復活!
と行きたいところなのですが……まだちょっと不十分のようです。
まったく情けない(T-T)。
今、メソド(メッセージ式)の最終行の「^」について悩んでいます。
たち
self allInstances inspect
たちの数は?
^ self allInstances size
という以前の例題の「^」の有無の意味(理由)が理解できないでいます。
クラスライブラリィをちらりと覗くと、やはりメソドの最終行は「^」です。
これがないとうまくPrint-itで正しく評価されないことは経験的にわかりますが……。
おさらいページをまた後退した内容で汚すのに躊躇したのですが、ついに降参ですm(_ _)m。--さ茂(正しい読みを「さも」に決めました)
掲示板を拝見いたしました。KY さん、フォローをありがとうございます。
さて、さ茂さん(「さも」さんで晴れて辞書登録できます(笑))。おそらく、print-it およびブロック内処理(あるブロックに value を送った結果)のときと、メソッドで同じ処理を記述したときの挙動(値の返し方)の不一致がさ茂さんの感じておられる違和感を引き起こす原因のひとつなのではないでしょうか。
1. 2. 3. 4. 5
を print-it すると最後の 5 が返り(プリントされ)ますが、
てすと
1.
2.
3.
4.
5
というメソッドを適当な場所、たとえば 人間 class に定義して「人間 てすと」とすると、5 ではなく、人間が返ってきます。これはKYさんのコメントにもあるように、メソッドの場合は最後に ^self が隠れている、つまり、
てすと
1.
2.
3.
4.
5.
^ self
となっているのだと考えるとよいのかもしれません。--sumim - 2002-07-19, 21:24:12
なるほどです。
>おそらく、print-it およびブロック内処理のときと、メソッドで同じ処理を記述し
>たときの挙動(値の返し方)の不一致がさ茂さんの感じておられる違和感を引き起こ
>す原因のひとつなのではないでしょうか。
不一致ですね(^-^;)。ものすごい初歩的な誤りだったわけですね(^-^;)。
で、おさらいなのですが、
「^」は、処理を中断して続くメッセージ式を処理してそれ以後の処理をキャンセルする。特にメソッド内では最終処理を明示するために必須。
と考えればよろしいでしょうか?
ついでにもう一点。
掲示板でも悩んでいたんですが、メソッド内で宣言した一時変数(と同名の何か?を)を最終行で「^」で処理する意味についても理解できていません。
一時変数というのはそのメソッド内だけ生きる名札。ですからその名札にいろいろな処理(例:登場人物=性別や髪の色、好意印象初期値を代入するために使用。本体は「ある人間(ムーンレイスor人間)」)を施して……どうして最後にその名札を「^」するのか? 理解できていません(T-T)。--さ茂 - 2002-07-19, 22:09:42
>初歩的な誤り
「誤り」というほどのものではなく、メソッドは一見すると print-it でできる作業を定型化してシステムに組み込んだだけのもので、print-it と同レベルのものと見なすこともできるのですが、それだと説明できなかったり同じ感覚では利用できないもの(^ の挙動や self など)も出てくるので注意が必要だということでしょう。
>で、おさらいなのですが、《中略》と考えればよろしいでしょうか?
「最終処理」を「刺激の反応としてどんなオブジェクトを返すかを決めるための最終処理」としていただければよりよろしいかと。
>メソッド内で宣言した一時変数(と同名の何か?を)を最終行で「^」で処理する意味
たぶん変数のご理解がまだ十分でないのだと思います。
- 「同名の何か?」→名札の名で参照できる(名札に繋がっている)オブジェクト
- 「そのメソッド内だけ生きる名札」→そのメソッド内だけで使用できる(あるオブジェクトとの繋がりを維持できる)名札
- 「その名札にいろいろな処理を施して」→その名札を通じて、そこに繋がっているオブジェクトにいろいろな刺激を与えることで内部状態を変化させて
- 「どうして最後にその名札を「^」するのか?」……そのメソッドを実行する刺激の反応として その名札に繋がっているオブジェクトを返すことを明示するためです。
くどいようですが、名札に対するご理解をもう少しなんとかしておいたほうが良いかも知れませんね。あるいは名札という置き換えがいけなかったのかも。--sumim - 2002-07-19, 22:44:33
いや、よく読み返してみると表現の問題だけで名札に関するご認識には問題はないのかも知れません。むしろ「Squeak における“処理”とはなにか」のほうでしょうか。たしかにこれは DOS のバッチ処理やエクセルのマクロなどでの変数(箱やセルのようなもの)と Squeak における変数(関連づけ)との違いと同様に、少々、頭の切替えが必要なもののひとつかも知れません。--sumim - 2002-07-19, 23:44:52
DOS のバッチ処理やエクセルのマクロでは自分(もしくはその代わりをしてくれる機械のようなもの)が材料を詰め込んだり作業をするための箱のようなものを前にして具体的にどんな作業をするのかを忠実に記述したものが“処理”だと言えます。たとえば、3 + 4 という処理は「手元に 3 を持ってきて、4 を足す作業をすると、結果として手元に 7 が残るのでそれが答えだ」という感じになると思います。
Squeak では同じ 3 + 4 と記述してもちょっと様子が異なります。自分は主役ではなく、あくまで傍観者のひとりに過ぎません。同様に、記述を忠実にこなす機械のようなものも、手元に作業場の役割りを果たす箱のようなものも想定する必要はありません。しいて主役を挙げるなら、Squeak 自体、もしくは刺激を受け取る 3 ということになります。Squeak で我々が記述する“処理”はすなわち「彼、つまり 3 に“+ 4”という刺激を与える」という筋書きかト書きのようなもので、我々、傍観者はその結果がどうなるか(3 が刺激を受けた結果、どんな反応を返すのか)を文字通りかたわらで見ているだけ…と切り換える必要がある、という例えはかえって分かりにくいでしょうか?--sumim - 2002-07-20, 00:03:39
>くどいようですが、名札に対するご理解をもう少しなんとかしておいたほうが良いかも知れませんね。
表現力も理解力ももう手の施しようがないです。学習能力とセンスの無さに(T-T)が……。
一時変数が表わすものは、たとえば新しく作ろうとしている'ミラン・レックス'という名の灰色の瞳の「あるムーンレイス」・男性、名札(グローバル関数の方)がミランだとして、これにムーンレイスの初期値として好意対象にディアナを設定するためのメッセージ式だと理解しています。
初期値さえなければ必要ない変数だったはずです。
これが、
>する刺激の反応として その名札に繋がっているオブジェクトを返すことを明示する
という点がまだ合点がいきません。
オブジェクトを返す、必要があるのか? です。
すでにミランというグローバル変数(名札)のついたあるムーンレイスに、髪の色や性別は登録されていて、ムーンレイスの初期値「好意対象=ディアナ」も設定された後に、どうしてもう一度「登場人物」につながった(この場合)ミランを返す必要があるのか?
実際、最後に「^」で関係のない、あたりさわりのない処理(たとえば'処理終わり')とすると、ミランの中身は「'処理終わり'」になります。
もう救いようがないほど根本的な不理解があります(T-T)。
このメソッドの式の途中の処理は最後に^登場人物を返さないと完成しないことはわかりました。
逆に言えば、いろいろ工夫していろいろなメッセージ式を考えても、最後の1行ですべての変化はちゃらになってしまうのですね?
オブジェクト メッセージA メッセージB メッセージC メッセージD
の基本に戻ると、
ミランというあるムーンレイスにはAで名前が入り、
出来た名付きミランがBで瞳の色が入り、
灰目'ミラン・レックス'のミランは自分が属する種族の普遍的好意対象のディアナをCで登録され……。
最後の行で不用意に準備された「処理終了メッセージ」に食われて今までの成長(生成)はすべて消え去る。
だから最後に、処理され変化したミラン自身をミランに返す必要がある?
↑絶対違うと思います(T-T)。
なぜ「あるムーンレイス」として様々な特徴を付加し、完成直前だったミランが、ムーンレイスであることはおろか人間であることすらやめて'処理終わり'という文字列に落ちぶれるのか?
そしてもう1点。
たち
self allInstances inspect
たちの数は?
^ self allInstances size
上は「^」が必要でないのは、inspectとsizeの二つのメッセージの性質が違うからでしょうか? --さ茂 - 2002-07-20, 00:12:54
>inspectとsizeの二つのメッセージの性質が違うからでしょうか?
inspect と size というよりは、たち と たちの数は? というメッセージをそれぞれ、あるオブジェクトに送った結果、どんな反応が返ってくることを期待するかの違いだと言えます。--sumim - 2002-07-20, 00:23:24
処理についての追記がありますので、遡って、ちょっと目を通してみていただけますか? --sumim - 2002-07-20, 00:26:55
理解力想像力の欠如を補うべく、また(危険かも知れない)実験をしました。
正しい評価:
ムーンレイス たち Arrayのインスペクタが正しく表示
ムーンレイス たちの数は? 4 これで正解。
あえて「^」を両者取り違えてみましたら、
ムーンレイス たち ちゃんとArrayのインスペクタを表示。
ムーンレイス たちの数は? ムーンレイス ×
つまりinspectというメッセージは、「^」或無関係なくインスペクタを呼び出す。
sizeというメッセージは、そうではない。
どんな反応を期待するか、ということですが、クラスライブラリィをちょっと覗いてみます。またレスポンスが悪くなるかもしれませんがm(_ _)mよしなに。--さ茂 - 2002-07-20, 00:44:50
たち
self allInstances inspect
の inspect は ^ の代わりをしていると考えるのはどうでしょう。本来なら、
たち
^ self allInstances
とするところを、返すべきオブジェクト(self allInstances の結果) に inspect を送信して別ウインドウにそれを表示する方法を選んだという説明では駄目ですか?
実際に、「ムーンレイス たち」を do-it ではなく print-it すると (インスペクタはあいかわらず表示されますが)、print-it の結果(たちの数は? で数が表示される場所)には ^ がない たちの数は? と同様に ムーンレイス が表示されるはずです。--sumim - 2002-07-20, 01:40:42
>の inspect は ^ の代わりをしている
(^-^;)。inspectというメッセージ、コマンド+iのinspect-itと同じ反応を返すものだとはわかりますが、それをメソッドで扱う時はこれですね?
実は理解していませんでした。
「^」の代わりのinspect?
これはinspectというメッセージがその式のある場所に評価結果をprint-itせずモルフのインスペクターの窓を表示して見せる、だからその場(普通ワークスペース?)に評価をprint-itさせるために必須な最終行の「^」はいらない。一方、sizeはArrayの中の要素数を返すメッセージなので、どこかに返値を表示しなきゃならない。だからワークスペースに吐き出すように「^」は必要。……なのでしょうか?
↑ミランが'処理終わり'にとりつかれて別人(非人間)になる問題も含めて、ばっさりと斬り捨ててくださいm(_ _)m。
>実際に、「ムーンレイス たち」を do-it ではなく print-it すると……
半信半疑なまま進んでいますが、「.」でメッセージを区切って2つ同時に行う場合と挙動が違うのですね? これはなぜでしょうか?
あぁまた謎が増えた(T-T)。
「.」はメッセージ式の区切りとして使えるから以前にも人物登録のメッセージ式で複数人数登録でこれを使って一括do-itしましたよね?
print-itで評価を得たい時には実は使えなかったのでしょうか?
はてさて?
*正常なメソッド print-itすると?
ムーンレイス たち. =Arrayのインスペクタ表示
ムーンレイス たちの数は? 5
do-itすると?
ムーンレイス たち. =Arrayのインスペクタ表示
ムーンレイス たちの数は? =反応無し
*「^」とっかえ print-itすると?
ムーンレイス たち. =Arrayのインスペクタ表示
ムーンレイス たちの数は? =ムーンレイス
do-itすると?
ムーンレイス たち. =Arrayのインスペクタ表示
ムーンレイス たちの数は? =反応無し
で、これを1行ずつ行うと、sumimさんのおっしゃるとおりムーンレイスを返します。
また、「^」とっかえパターンの
ムーンレイス たち =
#(ムーンレイス の: 'ロラン・セアック' ムーンレイス の: 'ディアナ・ソレル' ムーンレイス の: 'テテス・ハレ' ムーンレイス の: 'テストくん' ムーンレイス の: 'キース・レジェ')
と、Arrayな(?)配列を返しました。なんだか不思議です。 --さ茂 - 2002-07-20, 09:32:12
>「.」はメッセージ式の区切りとして使えるから
あっています。
>print-itで評価を得たい時には実は使えなかったのでしょうか?
そうですね。ピリオドで区切られた複数のメッセージ式を print-it したときは、それまでの式を do-it し、最後の式の値だけプリント(print-it するために選択したテキストの最後に挿入)されるので、すべてのメッセージ式の結果がプリントされるわけではありません。たとえば、先に出てきた、
1. 2. 3. 4. 5
の print-it の結果は 5 だけでしたよね。もし、すべての式の結果がプリントされるのなら、1 から 5 までの数字が列挙されるはずですが、そうはなりません。私はてっきり、一行ずつ print-it しておられるものと勘違いしていたので、説明が足りなくて申しわけありませんでした。ちなみに、さ茂さんのコメントにもありますように、これまで、一気に複数のムーンレイスたちの設定を行なうような場合の複数の式の最後にはピリオドを付けるよう心がけていました。そうでない、一行ずつ評価(do-it、print-it) していただきたいものは、ピリオドはつけずに、また、行が連続しないように空行を設けたつもりです。--sumim - 2002-07-20, 12:22:04
>Arrayな(?)配列を返しました
これは、Array のインスペクタを表示させたときに self をクリックして呼び出すことができる右枠の内容と同じはずです。Array やその仲間たちについてはまだ説明がすんでいないのでまったくの余談ですが、人間 >> #printOn: 同様、Array >> #printOn: も、ある条件(要素の数が少なく、かつ、すべての要素がシンボル・文字列・文字・数値のいずれかである)が整えば、それ自身を表わす表記を吐きだしてくれます。たとえば、#(1 2 3 4 5) や #('this' #is $a 10) などはこの条件を満たしているので、print-it や inspect-it (の self 欄を見た)ときにそのままプリントされ、なおかつそれを別のメッセージ式の一部としてそのまま利用できるはずです(print-it の結果を print-it しても同じ結果になる)。--sumim - 2002-07-20, 12:30:32
移動しましょう。
このページを編集 (31967 bytes)
|
以下の 2 ページから参照されています。 |
- ロランとディアナ6 最終更新: 2002-07-08, 20:47:14 <192>
- 復習のページ2 最終更新: 2002-07-21, 13:31:27 <192>
This page has been visited 3414 times.