下の入力ボックスに書き込んで“テキストの追加”ボタンで登録出来ます。 修正したい場合はページ上のアイコンの“edit”で出てくる画面で編集可能です。
|
Monday, 30 October 2006, 7:30:39 pm
はじめまして、ノッシといいます。smalltalk(VisualWorksで)を初めてまだ一週間位の初心者です。色々なホームページを見ながら勉強を続けています。
その中でシステムブラウザでクラス作成時に使うテンプレートが、ホームページ毎に違い戸惑っています。defineClassというメッセージを使う場合とsubclassというメッセージを使う場合があるようです。試しにdefineClassで書かれたテンプレートをsubclass版に書き換えてみたのですが、問題なく動作しました。あちこちのホームページを見て回るとどうも、subclassを使っているホームページはVisualWorksのバージョンが古いみたいなのですが…。
何故途中からsubclassは使われなくなったのでしょうか?それと、もう使わない方がいいのでしょうか?smalltalk subclassで検索すると、smalltalk defineClassより圧倒的に多いのも気になって…素直にdefineClassを使っていいものやら不安で不安で…。どなたかよろしくお願いします。
- ノッシさん、こんにちは。私も昔はVisualWorksバリバリだったのですが、最近の環境のことはよく分からなくなってしまいました。この手の質問はSMLでされると、きっとレスが付くと思います。--abee
Sunday, 31 October 2004, 4:17:06 pm
abeeさん花火の件です。花火本体のClass fireworkと 花火屋FireworkManの
Classをつくり、Fireworkで花火を発射し、FireworkManで発射の合図を送るようにしました。FireworkMan のstepを用いて発射するわけです。
1)最初はstepTimeで間隔を決めましたが、ハードの環境によって時間が変わり、安全を見て長めに設定すると冗長になります。
2)Global 変数を設定して、これに星の数をいれて両Classから参照するようにしました。変数の設定にはなにか引っかかるものあります。
3)FireworkManのClass のClassInstance変数に星数を設定して両Classから参照するようにする。
結局3)でやることにしました。
サクサクSmalltalkによればClassInstance変数はあまり使わないとありますが特に問題ありませんでした。
naming とcodingには気をつけましたが、まだまだです。--kenk
Sunday, 10 October 2004, 2:42:32 pm
abeeさん 有難う御座います。
私には難しいご返事でしたが、まず分かりましたことは、今の「花火」は花火のような絵を描くことに気が行っておりましてモデルといった観点は希薄でした。一旦燃え尽きた星を再利用するとか、リレーのように前の星が後の星に発射のメッセージを送るとか現実離れしたフローを取っておりました。(スピードを上げるための対策でもありましたが)
花火自身の自動運転よりは、花火屋または発射コントローラーの指示に従ってうちあげるほうが自然です。
考え方が分かりやすく伝わることを第一に、速さは機械にもよりますすので星の数でまずは調整するようにして、再トライすることにします。
モデリングについては、「米粒を一粒づつ落としてで山をつくる」とか「山火事」のモデルとかやってみたいものがありますのでやりながら勉強(息が続けばの話ですが)するつもりです。今後ともよろしく願います--kenk
Tuesday, 5 October 2004, 8:41:58 pm
kenkさん、よろしくお願いします。
あるメソッドをどこに定義すべきかという問題は、そのメソッドを起動するメッセージに答えるべきなのは誰か、即ち、その問いについて責任を負うべきオブジェクトはなにかという問題に置き換えることができます。クラスもまたオブジェクトですから、クラスが責任を負うべきと考えるのであればクラスメソッドですし、インスタンスであればインスタンスメソッドです(この際、クラスとインスタンスの本質について考える必要があります)。
このことは、メソッドだけでなく変数の場合でも同様で、判断の基準はそのオブジェクトが知っているべきことかどうかになります。
あるいは、お書きになっているように、管理するためのオブジェクトを別に作って、それに任せるべきかもしれません。もし、そこまで思いをはせるのであれば、もはやそれはプログラミングの領域ではありません。これは分析や設計と呼ばれる段階の話になります。
古典的なオブジェクト指向分析では、現実のシナリオから問題領域に登場するオブジェクトを抽出して、それらの関係を明らかにします。即ち、静的(クラス図)、動的(状態遷移図)、機能的(データフロー図)な各側面に着目して、現実を反映したモデルを作ります。このモデルを実装する環境に応じて、変形する過程が設計になります。実装は設計をプログラミング言語などで置き換えたものです。
また、このそれぞれの段階において、繰り返し現れる構造があります。建築設計の例であれば、上がりがまちは必ず廊下に続く(これはちょっと適当)とかいったようなものです。これを毎回考えるのは面倒なので、再利用可能な形で整理したものがデザインパターンです。
煙に巻くようで恐縮ですが、言いたかったのは、「オブジェクト指向分析・設計」「デザインパターン」というタームと共に「花火の打ち上げとは何か」から再スタートしてみるのも悪くは無いのではということです。--abee
Sunday, 3 October 2004, 4:12:48 pm
伊藤(kenk) です。よろしくお願いします。
最近 superserverを使おうと思いましたが、pluginで読めるversionであることが条件との結論で英語版3.6でcodingを行いました。やった範囲ではうまくいっております。(少しのギャップはありましたが)
昨年作った花火(Firework)を再codingしました。疑問点がありましたので教えてください。
1)花火は100個ぐらいの星からできております。100個のインスタンスはclass methodを使い作りました。これでよいのでしょうか?
別に星をコントロールするclass(FireworkRoot)を使うやり方もあるのですが。
2)星には2種類の変数、星共通の変数、発射位置とか星の色等と、星固有の変数があります。共通の変数はクラス変数で、各星ごとの変数はインスタンス変数に割り当てました。 これでよいのでしょうか? これもちがうクラスの変数に割り当てることできるのですが。
以上教えてください。
蛇足 eToyとでは変数の扱いちがいますので混乱しました。昨年はインスタンスをsmalltalkでつくり、その制御はWorkspaceで確認、そのスクリプトをeToyのObjectのscriptにしボタン化しました。smalltalkを使おうと回り道しました。--kenk
- クラス変数とインスタンス変数(メソッドも)どちらにするか迷っちゃうですよねえ。(単に理解してないだけのおいらですが)おいらなんか出来る限りインスタンス変数&メソッドで済ませちゃってたりするです。でへへ。梅澤さんの超ウルトラSqueak本(おいおい勝手に名前を変えるなって〜の)も出ることですし、ここら辺はがっちりとこの本で学ばせてもらいやしょうおおお!!(笑)--thoru
Monday, 30 August 2004, 3:03:13 am
確かに間があきすぎるとついつい忘れてしまいがちになりまする。(汗)
で、前の書き込みを見ないで覚えていることを頼りに答えることに
して、そのあとでもう一度今までの書き込みを読むことにしまする。
なので、間違えてたらびしばしとお願いいたします。--thoru
FileStream fileIn: 'tToyTools.st'
レシーバ
FileStream
セレクタ
fileIn:
引数
String
(FileStreamのクラスメソッドfileIn: に以下のコードを追加し実行
Transcript cr show: fullName class.)
Saturday, 28 August 2004, 3:24:42 am
ここで突然過去に戻ります。
FileStream fileIn: '***.cs'
どうやら無事ファイル・インされたようなので(これだけでもおいら的にはゲッチュ!でした)
ここで使われているメッセージ式のレシーバ、セレクタ、引数のクラスを教えてもらえますか。--abee
Saturday, 14 August 2004, 1:40:31 am
シカゴから生還しました。いろいろ片付けているので、もうちょっとお待ちください。--abee
Sunday, 8 August 2004, 2:39:09 am
defaultSARHandlerメソッド中で使われているメッセージセレクタは・・・・・・
sendersボタンをクリックするとでてくる項目が
そうではないかと。
type:extension:action:
new
fileInFrom:
blockCopy: <これが正直謎(ブロックのこと?)
- 当たりです。blockCopy:は・・・気にしないでください。これらはsendersを使わなかったとしても見つかられましたか。--abee
- sendersを使わなかったら見逃していたと思います。--thoru
fileInFrom:のレシーバとなるクラスは・・・・・
SARInstaller クラス
引数streamのクラスは・・・・・
まずdefaultSARHandlerを下記のように書き換えます。
defaultSARHandler
^ ExternalDropHandler
type: nil
extension: 'sar'
action: [:stream |
Transcript cr; show: stream class.
SARInstaller new fileInFrom: stream]
これでsarファイルをワールド内にドロップインしますが
Transcriptには何も表示されません。
ブロック内ではTranscript show:は使えないってこと?
(実はここでへこたれてしまい半週間経過でありました・・・涙)
- このやりかたは大正解です。じゃあ、なんで表示されないかというと、defaultSARHandlerは、SARを扱うためのデフォルトのオブジェクト(ハンドラ)を返すメソッドだからです。このオブジェクトはExternalDropHandlerを初期化するときに登録され、ドロップインのときは同じオブジェクトが毎回使われます。この初期化をどこでやっているかというと、defaultSARHandlerのsendersに答えがあります。
ただ、この話は今やっていることからそれるので、ちょっと置いておきたいような気がします。--abee
で、fileInFrom:はSARInstallerのメソッドってことなのでこっちの方を書き換えることにします。
fileInFrom: stream
"The zip has been saved already by the download.
Read the zip into my instvar, then file in the correct members"
| preamble postscript |
Transcript cr; show: stream class.
[
stream position: 0.
zip _ ZipArchive new readFrom: stream.
・・・・以下省略・・・・・
でまたまたsarファイルをワールド内にドロップ・インします。
おお!!出てきたですううう。
MultiByteFileStream クラス
ってことでどうでしょう?--thoru
Monday, 2 August 2004, 1:14:41 am
明日からSqueakfestに行ってきますので、これまでにもましてレスポンスが悪くなると思います。すみません。--abee
- がんばってきてください!!スクイークフェスタの準備がたいへんだったのに、お付き合いありがとうでする。--thoru
Monday, 2 August 2004, 1:11:42 am
ここまでに出てきたいろいろなテクニックを使って、ExternalSARDropHandler.prを読み込んだイメージで、ExternalDropHandler>>defaultSARHandlerをブラウザで開き、このメソッド中で使われているメッセージセレクタ、fileInFrom:のレシーバとなるクラスと引数streamのクラスを調べる方法を考えてみてもらえますか。--abee
Tuesday, 27 July 2004, 11:49:05 pm
再度挑戦です。
まちがえたところのひとつは「引数の名前」ではなく「引数のクラス」だということ。
これはちょっとアバウトに答えてしまった結果のミスでした。(汗)
もうひとつの「クラスの名前」は「addAllMorphメッセージを受け取ったクラス」。
(メソッドを実装しているのはスーパークラスのMorphクラス)
- そうです。これは実行時にスーパークラス階層をたどってメソッドの探索が行われた実例ですね。--abee
Transcript cr; show: self class.
を見たときに「Morph」と表示されると期待していたのですが表示されたのは「TransformMorph」。
「self」はMorphのインスタンスのはずだしそのクラスということだから「Morph」が表示されると
思って・・・で、ちょっと動揺して混乱していたかも。
こんどはどうでしょう?--thoru
- よかったと思います。一瞬、後退してしまったかと思ったのですが、杞憂でした。--abee
- 杞憂じゃないかも・・・「引数のクラス」は答えるときについ丁寧さに書けた結果ですが「レシーバのクラス」については実際、後退していたかもです。いままでのことがちゃんと繋がっていないということだと思うですが、実際「レシーバのクラス」と答えようかどうか迷って結局、確信持てなくて別のいいかたにしてしまいました。(汗)<やっぱ後退してる・・・・。--thoru
Tuesday, 27 July 2004, 10:42:57 am
間が開いてすみませんでした。--abee
- こちらも、けっこう間を空けてやってまする。じっくり考えていたつもりがミスばっか・・・。(涙)--thoru
Saturday, 24 July 2004, 3:50:06 pm
addAllMorphs: aCollectionにコード2行を追加してAlt+sすると
TransformMorph Array
がトランスクリプトに表示されました。
次にMorphクラスをbrouse hierarchyすると
AbeeSmalltalk.image
- これは関係ないですよね。--abee
- イメージを保存したときトランスクリプトに表示されたものを、まちがって一緒に引っ張ってきてしまったようです。すみません。--thoru
TransformMorph Array
TransformMorph OrderedCollection
TransformMorph Array
TransformMorph Array
TransformMorph Array
TransformMorph Array
TransformMorph Array
TransformMorph Array
がトランスクリプトに表示されます。むむむ。
次に「部品」フラップから楕円モーフを出してみます。
・・・・何も表示されない。
楕円モーフをゴミ箱へ捨てると
AlignmentMorph Array
PasteUpMorph Array
が表示されます。
オブジェクトのカタログを出してみると
AlignmentMorph Array
AlignmentMorph Array
が表示されます。
トランスクリプトに表示される場合は
addAllMorphs: aCollectionメソッドを使っていることがわかります。
そのときクラス名と引数名がトランスクリプトに表示される。
表示されない場合はこのメソッドを使ってない。
- 「クラス名と引数名が」ですか。うーん。Try againでお願いします。--abee
今までの流れで考えると引数を知るためには
この方法はとても有効な方法だと思います。--thoru
Friday, 23 July 2004, 1:51:31 am
システムブラウザでMorph>>addAllMorphs:を開き、コードビューに表示されているメソッドを見てください。
addAllMorphs: aCollection
| inWorld myWorld itsWorld |
myWorld _ self world.
inWorld _ myWorld notNil.
(以下省略)
これに、以下の2行を追加します。
addAllMorphs: aCollection
| inWorld myWorld itsWorld |
Transcript cr; show: self class.
Transcript tab; show: aCollection class.
myWorld _ self world.
inWorld _ myWorld notNil.
(以下省略)
変更したら、黄ボタンメニューの「了解 (s)」で保存します(余談ですが、このタイミングで、このソースコードがコンパイルされてバイトコードになります)。
トランスクリプトを開き、適当に操作してみて、何をしたときに、トランスクリプトに何が表示されたかと、そのことから分かることを教えてください。例は数個で結構です。--abee
Friday, 23 July 2004, 1:41:15 am
ここからシステムクラス(Squeakの動作に必要な基本クラス)のメソッド定義を変更していきます。場合によってはSqueakが死にますのでご注意ください。
もしそうなっても落ち着いて再起動すれば大丈夫です。
ただし、死にかけたときにスナップショットを撮る(イメージの保存をする)と、その状態のまま記録されるのでお気をつけください。このあたりの感覚はRPGと同じです。--abee
Wednesday, 21 July 2004, 4:41:30 am
システムトランスクリプトはご存知ですよね。ちょっとこれを使ってみましょう。
ワールドメニューの「開く・・・」から「transcript (t)」を選んで適当な場所にトランスクリプトを開いてから、次の式をそれぞれ評価してみてください。
Transcript show: 'hello'
Transcript show: 3 + 4
Transcript show: 'hello' class
文字が続いて分かりにくいときは改行できます。
Transcript cr.
Transcript show: 'hello'
このように複数のメッセージ式でレシーバが同じときは、「;」(セミコロン)を使って、レシーバを省略できます。
Transcript cr; show: 'hello'
これをカスケード(滝)と言います。
show:の引数をいろいろ変えて試してみてください。--abee
- トランスクリプトは何回か使ったことはあります。(つい最近になってからだけど)改行もやったことがあるんですが、ここで教えてもらうまでカスケードだという認識はなかったです。「あ、ほんどだ!」といった具合です。(汗)カスケードも知ってはいても何度もそれを忘れていて、何でこうゆう式になるんだろうと戸惑うこともよくあります。で、いくつかトランスクリプト試してみました。ここにその結果等は書いたほうがいいですか?<今回はとりあえず省略しましたが・・・。--thoru
- 私は、カスケードはレシーバが分かりにくくなるので、なるべく使うべきではないという立場でなので、軽く流してもらって結構です。ただ、Transcriptの場合は使わないと面倒なので。
結果については、書いていただかなくても大丈夫と思います。--abee
Monday, 19 July 2004, 6:21:34 pm
レシーバのクラスはと「submorphs class 」を評価して表示すると
「UndefinedObject」となります。
・・・ってことは?
このsubmorphsっていうのはownerのサブモーフということたから
Morphの集合(Collection)ってことになるですねえ・・・・
- 妥当な推測です。--abee
- 複数形の「s」がついているのもチェックポイントですね。つまり、この変数名はsubmorphの集合(コレクション)であることを示唆しています。--abee
じゃあそのクラスはというと・・・・どう調べるのでしょう?(涙)
- そうですね。それが問題。--abee
- これはもうちょっとトライしてみた方がいいでしょうか?--thoru
- いえ、やりかたはもう少しお待ちください。--abee
それでは引数のクラスは?とまたまた「aCollection class」を試しますと
「UndefinedObject」となります。
- これもそうなります。メソッドの中で使われているsubmorphsやaCollectionなどの変数は、実際にインスタンスを作って、メッセージを送り、メソッドを実行しないと値が決まりません。断片だけの評価はできないのです。--abee
- だからトランスクリプトが上ででてきたわけですか?<と推測してみる。--thoru
でで、引数の「aCollection」はaddAllMorphs: の引数でもあるので
senderを見てみることにします。
リストのいろいろある中からPastUpMorph>addAllMorphs:をみますると
addAllMorphs:の引数名がarrayとあるので引数はarrayというかArrayクラスかな?
もうひとつの例としてPluggableButtonMorph>class exampleにいいのがありました。
addAllMorphs: (Array with: b1 with: b2 with: b3)
なので引数はArray クラス。(ああ、目が回る・・・)--thoru
- グレートです。--abee
- ただ、この場合はArrayだけに限った話ではないと思います。aCollectionと言った時は、そのサブクラス階層に含まれるクラスも含むのが暗黙の了解です。ArrayはCollectionのサブサブサブクラスですね。--abee
Friday, 16 July 2004, 9:07:43 am
同様に、Morph>>addAllMorphs:の中で送られているメッセージセレクタ「,」を含むメッセージのレシーバと引数のクラスを推測して教えてください。--abee
- もうしばらくお待ちくださいね。<けっこう悩んでいたりして・・・・(汗)--thoru
Friday, 16 July 2004, 8:58:16 am
なのですが、すべてのメソッドに実行可能な例がついているわけではありません。でも大丈夫、Smalltalkのクラスライブラリには例が大量に含まれています。
システムブラウザでSequenceableCollection>>,を選択し、右上のペインの黄色ボタンメニューから「senders of... (n)」を選ぶか、中央左の「senders」ボタンをクリックし、続いて開くメニューから「,」を選んでください。
これがSmalltalkのシステム中でメッセージセレクタ「,」を含むメッセージを送っているメソッドの一覧です。センダ(送信者)はレシーバ(受信者)の対になる言葉ですね。
適当なメソッドを選択して、「,」のレシーバや引数を見てみてください。一見して、CollectionやStringのインスタンスだと分かるものもありますが、そうでないものもあります。たとえば、FileStream>>fileInを探してみてください。このメソッドの末尾にある、
'Loading ', self localName
は、直接実行して試すことはできませんが、'Loading'のクラスがStringであることから、引数の「self localName」の返り値もStringのインスタンスであることが推測できます。--abee
Friday, 16 July 2004, 8:27:02 am
かように、メソッドの変数名やコメントは重要です。重要なのですが、その重要度に順序をつけるとすれば、
- 実行可能な例のコメント
- 適切な変数名(引数名を含む)
- メソッドの内容を説明したコメント
になります。一般にコメントと言えば3ですが、これよりも適切な変数名がついているほうがソースは100倍解りやすくなります(コメントがすごく丁寧でも変数名がt1, t2だったりすると最悪)。さらには、メソッドに実行可能な式がついていれば、実際にそれを試して調べられるので超便利です。
これらのことは、メソッドを使う立場ではなく、作る立場になったときに気をつけないといけないことでもあります。--abee
Friday, 16 July 2004, 1:42:40 am
箇条書きにしてみました。--thoru
#(2 4 6 8) , #(who do we appreciate)
プリント・イットの結果
-->#(2 4 6 8 #who #do #we #appreciate)
レシーバのクラスを調べる
#(2 4 6 8) class
-->Array
階層(hierarchy)をたどりメソッドを探す
SequenceableCollection>>,
メソッドの定義されているクラス
SequenceableCollection
引数のクラス
#(who do we appreciate) class
-->Array
((2989 printStringBase: 16) copyFrom: 4 to: 6) , ' boy!'
プリント・イットの結果
-->'BAD boy!'
レシーバのクラスを調べる
((2989 printStringBase: 16) copyFrom: 4 to: 6) class
-->String
階層(hierarchy)をたどりメソッドを探す
SequenceableCollection>>,
メソッドの定義されているクラス
SequenceableCollection
引数のクラス
' boy!' class
-->String
- ありがとうございます。これでレシーバと引数のクラスは、コメントの記述や引数名が示しているものと同じことが確認てきました。--abee
Friday, 16 July 2004, 12:37:47 am
えっと、確認です。abeeさんはSqueakのバージョンはなにをお使いですか?
というのはおいらはここではNihongo6.1を使っているのですが、「SequenceableCollection>>,」にはコメントがないのです。Squeak3.5(おいらはこれをもっぱらSmalltalkの練習でつかってます)にはこのコメントはあります。ついでの質問といってはなんですが、このようなコメントがない場合(それも引数名がt1・・・涙)の対処方法も知りたいところでありまする。--thoru
- 私はNihongo6.1を使っています。
コメントが見えないのは、ソースファイル(squeakV3.sources)が正しい場所に無いからです。
このファイルが見つからない場合、ブラウザは自動的にコンパイルされたメソッドをデコンパイルしてソースコードを復元しますが、コメントや変数名などの情報は失われてしまいます。
このファイルは3.xベースであれば日本語版も英語版も同じなので、コピーしてVMかimageと同じディレクトリに入れた後にSqueakを再起動すれば次からはコメントや変数名が正しく表示されるようになるはずです。
たぶん、thoruさんは山宮さんのインストーラをお使いではないかと思うのですが、つい先日これにソースファイルが含まれていないことが分かりました。7/12以降は修正してもらっています。--abee
- なるほどそうゆうことですか。SqueakV3.sourcesが「SqueakV3」になってますね。SqueakV3.sourcesを入れるとちゃんとコメントが表示できました。ありがとうございます。--thoru
Thursday, 15 July 2004, 8:16:48 pm
メソッドのコメントは末尾にもう一つあり、ここには実際に試すことのできる式が書かれています。
これらの式を実際にprint itで実行した結果と、メッセージセレクタ,についてのレシーバと引数のクラスを教えてくたさい。--abee
Thursday, 15 July 2004, 8:11:38 pm
thoruさんが気付かれたように、引数を伴うメッセージの場合、その引数となるオブジェクトのクラスが期待するものと異なる場合はうまく動かないことがあります。
これがレシーバであれば、今までのようにクラスからスーパークラスをたどってメソッドを見つける方法でよいのですが、引数のときはこの方法が使えません。
そこで手掛かりになるのが引数名とメソッドのコメントです。SequenceableCollectionのメソッド,(これを「SequenceableCollection>>,」と表記します)の定義は以下のようになっています。
, otherCollection
"Concatenate two Strings or Collections."
^ self copyReplaceFrom: self size + 1
to: self size
with: otherCollection
"
#(2 4 6 8) , #(who do we appreciate)
((2989 printStringBase: 16) copyFrom: 4 to: 6) , ' boy!'
"
このとき、引数の変数名はotherCollection(他のCollection)で、コメントには「Concatenate two Strings or Collections.」(二つのStringやCollection同士を連結します)とあります。
このことから、引数に期待されるオブジェクトは、レシーバと同じStringクラスやCollectionクラス(とそれらのサブクラス)のインスタンスだろうと推測できます。--abee
Wednesday, 14 July 2004, 3:51:06 pm
'world' , 4649
これをAlt + pするとノーティファイアが出ます。
まず「'world' class 」でレシーハのクラスを調べるとStringクラスだとわかります。
次に「,」のメソッドを探す為に「brows hirarchy」でStringクラスのスーパークラスを
順番にたどって探すとSequenceableCollectionクラスにありました。なのでレシーバの「'world'」は
「,]メッセージセレクタを理解することが出来るのでメッセージセレクタには問題はないようです。
ということは後は残っている「,」の引数に問題がありそうです。
引数の「4649」のクラスを調べるとSmallIntegerクラスだとわかります。だとすると「,」メソッドを調べて引数の型がSmallIntegerクラスだと問題があることがわかればいいのだとは思うのですが、そこからどう調べていけばいいかわかりません。--thoru
Monday, 12 July 2004, 10:07:39 pm
ということで、本題です。
'world', 4649
の結果となぜそうなるかを教えてください。--abee
Monday, 12 July 2004, 9:25:58 pm
まず「 4649, 'world' 」をAlt + pすると
ノーティファイアが出ます。
ではなぜエラーになるのか調べることにします。
レシーバ「4649」にclassメッセージを送って
レシーバのクラスがなんなのか調べてみまする。
4649 class
をAlt + pするとレシーバはSmallIntegerクラスだとわかります。
今度はSmallIntegerをAlt + bしてブラウザを開いて
SmallIntegerクラスのメソッドに「,」があるかどうか探しますが
ここにはないようなので「browse hierachy」でスーバークラスに
該当するものがないかSmallIntegerの階層をたどって調べてみました。
ProtoObjectまでたどって探してみてもメソッド「,」はないようなので
レシーバの「4649」のクラスSmallIntegerは
「, 'world'」というメッセージを理解できない、
受け取れないということになります。
つまりエラーになるということだと思うです。--thoru
- もうなにも言うことは無いです。ばっちり。--abee
Monday, 12 July 2004, 7:34:25 pm
次の話に入ります。
'hello', 'world'
の結果は'helloworld'になります。では、
4649, 'world'
の結果となぜそうなるかを教えてください。--abee
Monday, 12 July 2004, 1:27:28 am
まずレシーバにclassメッセージを送ります。
#(3 4) class
すると「Array」が返ってくるので、このレシーバのクラスは「Array」クラスだとわかります。Array をAlt+bでブラウズしてメソッドに「+」があるかどうか確認すると見つかりません。次に「Array」を選択し「Browse hierarchy」でクラス階層を表示します。
ProtoObject
Object
Collection
SequenceableCollection
ArrayedCollection
Array
「Array」クラスの階層を上へたどって「+」メソッドを探しました。
メッセージセレクタ「+」に対応するメソッドが定義されているのはCollectionクラスです。--thoru
Sunday, 11 July 2004, 8:21:36 pm
ということで、質問です。
#(3 4) + 5
このメッセージ式が実行される時にメッセージセレクタ+に対応するメソッドが定義されているクラスを教えてください。--abee
Sunday, 11 July 2004, 8:04:18 pm
Smalltalkには型がないといわれますが、これは変数に型がない、つまりどんなクラスのインスタンスでも入りますよ、という意味であって、どんなオブジェクトにどんなメッセージを送っても動きますということではありません。なので、同じ「+ 4」というメッセージでも、それを受け取るオブジェクト(レシーバ)によっては、動いたり動かなかったり、動きが違ったりします。--abee
Sunday, 11 July 2004, 7:49:19 pm
ここまでで言いたかったのは、「セレクタを選んでAlt+b(ブラウザの「implementors」も同様)」はとても便利だけれども、あたかも同列にセレクタが並んでいるように見えるので、レシーバとメッセージ、オブジェクトとクラス、クラス階層、セレクタとメソッドなどの関係が分からないで使うと、ぜんぜん関係ないところにひっかかりますよ、ということでした。
あるメッセージ式を見たとき、レシーバからクラスを調べて、メッセージセレクタをそのスーパークラス階層から見つけて、実行されるメソッドを探すという練習は面倒ですがとても役に立ちます。
これが癖になるくらいやっておくと、式をぱっと見るだけで、いろんなことが分かるようになります。
その上で、implementorsを使うとこんなに便利なものはありません。--abee
- 以前よりは関係がはっきりとしつつあります。たしかにいままではメッセージセレクタを中心に調べていました。今回のレシーバから調べるという方法をどんどん取り入れていきたいとおもうです。--thoru
- たとえば、あるお店に行ったとして、「おやじ、いつものやつを頼むぜ」と言った場合に、おやじによって違うものが出てきたり、あるいは出てこないこともあるわけですね。重要なのは、「おやじ」であって、「いつものやつを頼むぜ」はその次です。まずはおやじの素性を知らなければなりません。--abee
- ううむ、素晴らしいたとえ話だ。「おやじ」から攻めるってわけやね。(笑)おいらの場合「いつものやつを頼むぜ」じゃなくて「あれね」で済ませてたかも。--thoru
Sunday, 11 July 2004, 7:27:19 pm
メッセージに答える方法がメソッドで、あるオブジェクトにメッセージが送られたときは、そのメッセージセレクタをキーにして、そのオブジェクトのクラスに定義されているメソッドを調べます。
見つかったらそのメソッドを実行し、見つからなかったら、スーパークラスを同様に調べます。
これを繰り返してProtoObjectでもまだ見つからなければ、メッセージが理解できない(MessageNotUnderstood)というエラーになります。--abee
- これは何度も繰り返してイメージしないと、ついつい短絡的に済ませてしまいそうなところです。要注意です。--thoru
Saturday, 10 July 2004, 11:17:26 pm
「+」に気をとられすぎて、「SmallIntegerのスーパークラス階層において」というのを完全に見落としていました。(汗)改めて、SmallIntegerをクラスを「show hierarchy」し階層を上にたどっていき「+」を探していくと「Number」クラスより上にはないようなので次に「Number」クラスを「show hierarchy」しました。各クラスのメッセージセレクタペインを探してみて「+」のあるものが以下のクラスでした。--thoru
Number
Float
Fraction
Integer
LargePositiveInteger
SmallInteger
- えっと、惜しいですが、まだちょっと違います。例えば、LargePositiveIntegerはIntegerのサブクラスではありますが、SmallIntegerのスーパークラスではありません。したがって、LargePositiveIntegerとSmallIntegerの間には継承関係はありません。お手数ですが、下の楽をする方法をヒントにもう一度お願いします。--abee
- 今度こそ大丈夫と思う心が落とし穴・・・。そうですね。ここでもまだ「+」にこだわりすぎて「SmallIntegerの」ということを忘れていますね。いかんいかん。(汗)このての間違いはこれからも多そうです。気をつけなければ。で、ヒント道理にやりました。
Number
Integer
SmallInteger
です。
- まだヒントに素直に対応できてないです。反省。--thoru
- いえ、かえって面白いです :-) 少なくとも私は。--abee
Saturday, 10 July 2004, 6:04:13 pm
SmallIntegerのスーパークラス階層において、メッセージセレクタ+に答えるためのメソッドが定義されているクラスをすべて教えてください。--abee
- 思いつくところAlt+bすることしかなかったのでやってみると「Implementors of +」とうウィンドウが出てきました。このリストがどうやらそのようです。ブラウザーで「+」を選択し「implementors」でも同様のことが出来ました。--thoru
AbstractSound
AbstractString
Collection
Color
Float
FloatArray
Fraction
Integer
LargePositiveInteger
MixeSound
Number
Player
Point
SmallInteger
Voice
- 残念ながら、この結果は正しくありません。たとえば、Colorのスーパークラスとサブクラスを確認してみてください。「SmallIntegerのスーパークラス階層において」に注意して、もう一度お願いします。--abee
- すこし楽をする方法をお教えします。クラスペインでSmallIntegerを選び、黄ボタンメニューから「browse hierarcy (h)」を選んで、クラス階層ブラウザを使ってみてください。--abee
Saturday, 10 July 2004, 5:39:49 pm
SmallIntegerのインスタンスが答えられるメッセージセレクタにsqrtがないのに、4がsqrtに答えられたのは、SmallIntegerのスーパークラスのスーパークラスであるNumberのインスタンスが答えられるセレクタにsqrtが含まれていたからです。
このように、あるオブジェクトが答えられるメッセージセレクタは、そのクラス自身とスーパークラス階層に含まれるクラスのインスタンスが答えられるセレクタを含みます。このことをメソッドの継承(インヘリタンス)と呼びます。
メソッド(方法)とは、オブジェクトが、あるメッセージに答える方法をメッセージ式をつかって定義したものです。
あるクラスにメソッドが定義されると、そのクラスのインスタンスが答えられるセレクタの一覧にそのセレクタが追加されます。この一覧がブラウザの右上のペインに表示されているものです。--abee
Saturday, 10 July 2004, 6:40:02 am
SmallIntegerクラスを「show hierarchy」すると
ProtoObject #()
Object #()
Magnitude #()
Number #()
Integer #()
SmallInteger #()
と表示されスーパークラスはIntegerだとわかりました。さらにIntegerクラスを「show hierachy」すると
ProtoObject #()
Object #()
Magnitude #()
Number #()
Integer #()
LargePositiveInteger #()
LargeNegativeInteger #()
SmallInteger #()
と表示されIntegerクラスのスーパークラスはNumberクラス、IntegerクラスのサブクラスはLargePositiveIntegerとSmallIntegerだとわかります。
Numberクラスにsqrtがありました。--thoru
Saturday, 10 July 2004, 5:00:21 am
クラスは、それぞれが独立しているのではなく、ProtoObjectクラスを根(ルート)とした木(ツリー)構造になっており、これをクラス階層と呼びます。
このとき、あるクラスから見て、上にあるものをスーパークラス、下にあるものをサブクラスと呼びます。スーパークラスはProtoObjectを除いて必ず1個、サブクラスは0個以上あります。
システムブラウザの左上から2番目にあるクラスペインでSmallIntegerクラスが選ばれている状態で、黄ボタンメニューから「show hierarchy」を選んでください。このとき、下のコードペインに表示されるのがクラス階層です。
SmallIntegerのスーパークラスを教えてください。また、そのスーパークラスのスーパークラスとサブクラスも教えてください。--abee
Saturday, 10 July 2004, 4:37 am
システムブラウザの右上にあるメッセージセレクタペイン(メソッドペインともいう)には、選択されているクラスのインスタンスが答えられるメッセージセレクタが並んでいます(インスタンス-クラス切替スイッチが「instance」で、メソッドカテゴリペインが「-- all --」のとき)。そして、thoruさんが見つけたように、SmallIntegerクラスにはsqrtというセレクタはありません。
であるにも関わらず、SmallIntegerクラスのインスタンスであるオブジェクト4はメッセージsqrtに答えられます。ここが不思議なところですね。--abee
Thursday, 8 July 2004, 11:46:20 pm
ここまでで、言葉の定義と、あるメッセージに答えられるかどうかは、レシーバのクラスによって決まることが分かってもらえたと思います。
次はこれの探し方です。今までは、メッセージセレクタを選択してAlt+bで探していたと思いますが、レシーバにclassを送って返ってきたクラスを選択してAlt+bしてみてください。
3 + 4
の場合は、
3 class
の返り値の、
SmallInteger
をAlt+bしてみてください。これで開くシステムブラウザの右上のペインから+というセレクタは見つかるてしょうか。
同様に、
4 sqrt
の場合も調べてみてください。--abee
- 「3 + 4」の例でレシーバ「3」のセレクタ「 + 」はシステムブラウザで見つかりました。同様に「4 sqrt」もやってみましたが開いたブラウザの右上のペインを探しても「sqrt」は見つかりませんでした。--thoru
Thursday, 8 July 2004, 2:40:29 am
Squeakのなかからっていうのも広すぎますね。
- すみません。なんでもいいという意味でした。--abee
単項メッセージ
'Squeak' byteSize
'Squeak' asHex
10 even
4 sqrt
二項メッセージ
'Squ' , 'eak'
'Squeak' = 'Smaltalk'
'ABCD' > 'AB'
10 \\ 3
キーワードメッセージ
'Squeak' at: 3
'Squeak' sameAs: 'eToy'
World color: Color gray
こんな感じで良いでしょうか?--thoru
- ありがとうございます。キーワードメッセージに一引数の例しかないのはなぜでしょうか。--abee
- 手ごろなものが見つからなかったというのもありますが、つい引数の1つのやつだけでもいいかなというのもありました。
Display fill: Rectangle fromUser fillColor: Color red.
Display flash: Rectangle fromUser andWait: 200
Form extent: 200@200 depth: 32
Array with: 10 with: 20 with: 30
でも改めて調べなおしてみるとやっぱりなかなか思うようなものが見つからない。キーワードメッセージの引数が複数のメソッドはあるのですが例としてソースコードにすることができなかった。<やっぱ、まだレシーバの理解があいまいなのか?--thoru
- いや、十分ではないでしょうか。例を持って来いと言われたら、脊椎反射でsendersなのですが、これはまた別の話。レシーバがクラスのオブジェクトばかりなのは、たぶん一行で実行できるようにしようとしたからですね。これは断片でも構いませんでした。すみません。--abee
Wednesday, 7 July 2004, 9:33:02 pm
もう少し、言葉の話を続けます。
メッセージには3つの種類があります。青字の部分がメッセージです。
3 class
3 + 4
3 max: 4
上から、それぞれ単項、二項、キーワードメッセージと言います。
単項メッセージには引数がなくメッセージセレクタだけでできています。
二項メッセージはひとつの引数を持ち、メッセージセレクタは記号で表されます。
キーワードメッセージはひとつ以上の引数を持ち、メッセージセレクタはコロンで終わる文字で表されます。
Squeakの中から、それぞれの種類についてメッセージの例を探して教えてください。--abee
- どうやらメッセージとメッセージセレクタの区別がよくわかってないのでそこのところをおねがいできますでしょうか。--thoru
- メッセージセレクタと引数を合わせたものがメッセージです。以下の例だと、緑がセレクタ、赤が引数になります。単項メッセージの場合は、引数がないのでセレクタだけでメッセージですね。--abee
3 + 4
3 min: 2 max: 4
Wednesday, 7 July 2004, 6:31:10 pm
言葉を整理しておきましょう。Smalltalkの式(メッセージ式)はすべて以下の形式になっています。
レシーバ メッセージ
これを踏まえて、
3 + 4
'hello' + 4
のレシーバとクラスを教えてください。--abee
- レシーバは3でSmallIntegerクラスです。
- まず調べる前にここで答えるという形式にしてます。答えてからそれらを調べてみるといった順序です。調べてみると今回の自分の解釈の間違いはすぐわかりました。<ほんとにめちゃくちゃでしたね。でもどうもこれが現在のおいらの理解力なのだとはっきりわかるのでいいかも。abeeさんはとほほ・・・でしょうが。--thoru
- そんなことはないですよ。最近、親にパソコンを教えたりしているのですが、それに比べれば1万倍は楽ですね。--abee
- 'hello'がレシーバでStringクラスです。--thoru
Wednesday, 7 July 2004, 5:36:20 am
したがって、Smalltalkの式では、メッセージが送られる相手、すなわちレシーバ(受取手となるオブジェクト)のクラスが何であるかを知ることが極めて重要になります。
3 + 4
'hello' + 4
これらの式のレシーバとそのクラスはそれぞれ何でしょうか。--abee
- +がレシーバだったと思いまする。
- ではそのクラスはなんだろうと、classのメッセージを送って試してみましたが
+ class
答えてはくれませんでした。
- この時点で+がレシーバではないことに気付いて欲しかったかも。「すべてのオブジェクトはclassに答えられる」ですから。--abee
- 例外なしというわけですね。つまりこれに答えられなかったものはオブジェクトではないということですね。--thoru
- ブラウズ・イットで見てみると
いくつか候補が出てきます。それらしきものはと考えてみて
Numberクラスでは・・・と推測しましたです。--thoru
- それなのでこれも違います。この推測方法は場合によっては悪くないのですが、このケースではあまりよくないです。--abee
Wednesday, 7 July 2004, 3:46:51 am
なんで私がここまでクラスにこだわるかと言うと、オブジェクトはそのクラスによって性質が異なるからです。中にはメッセージclassのように共通にできることもありますが、あるオブジェクトにはできて、あるオブジェクトにはできないこともあります。--abee
3 class
'hello' class
3 + 4
'hello' + 4
- 最後の行のコードが出来ないことの例ですね?--thoru
Wednesday, 7 July 2004, 3:14:44 am
実はあるオブジェクトのクラスを知る方法はとても簡単です。そのオブジェクトにclassというメッセージを送るだけです。
'hello' class
この式を「評価して表示」(print it)すると、結果はStringになります。つまり、'hello'のクラスはStringだということですね。別の言葉で言えば、'hello'はStringクラスのインスタンスだということになります。
classはなんにでも送れるので試してみてください。これでこれからは、私の「クラスを教えてください」攻撃はかわせるはずです。--abee
- 了解です。これは見覚えがあるコードです。<ただ繋がってないので活用できなかったやつのうちの1つ。さっそくやりまくってみまする。--thoru
- ブロック内のstreamのクラスは何かというもうひとつの問いがのこってました。で、すぐにつまづくわけですが、もうちょっと考えてみるです。--thoru
Wednesday, 7 July 2004, 3:04:58 am
一日数問だし、そんなにビシバシでしょうか :-) 別に何日も書き込みが無くても私は平気です。
今回のゴールは明確で、csファイルをドロップしてファイルインする仕組みをつくる、です。
あと、少なくとも私がここで書くことに裏は無いです。私は頓知のきいたクイズとか嫌いなので、字義通りに受け止めていただいて結構です。--abee
- ここまではまだまだ、イントロに過ぎないかも。(笑)それにおいらの物分りの悪さは1日1問どころか1問一週間、一ヶ月はあたりまえなのです。(涙)でも、どっちみちおいらにしてもこの続きは一人でも追いかけることになると思うので、とりあえずここでももうちょっと続けて見たいと思いまする。<abeeさん相手で贅沢言うのは超特大のもったいないお化けが出てきそうだし。ほんとうにだめになったら白旗をあげるかもですがよろしくお願いしまする。おてやわらかに・・・。--thoru
Tuesday, 6 July 2004, 5:13:11 pm
では、'hello'のクラスはなんでしょうか。--abee
- Stringクラスだと思いまする。
- あたりです。なぜそう思ったのか教えていただけますか。
- 実は'hello'のヒントを見る前、歩きながらも考えてたんですが、解ってあたりまえって感じでabeeさんが質問を出されてたので、どうやら知ってるはずのものを指しているのではと思ったわけです。で、このヒントを見てやっぱりというわけです。でもこれも勘です。ファイル自体かファイルの中身かと自問自答をしていたのですがやっぱ、どうやってブラウジングするのかわからなかった。しくしく。これがいちばんまずいわけでする。メソッドやクラスはそれなりにたどれる(といってもAlt+bですが)でそれなりに動いていけるのですが、今回はなにをどうしていいのかさっぱりでありましたです。<いまだに理由がいえない。というかファイルの中身はテキストだからStringってことでそう思ったというところでしょうか。--thoru
- (ううう、この流れは苦手だすなあ。このままビシバシモードへといくのかにゃあ???おいらには荷が重そうだああ。)--thoru
- そうかもしれないですが、このあたりで越えておかないといかんと思いますね、続けるなら。勘で使うにはSmalltalkは大きすぎます。例えばStreamのサブクラスだけで43個もあります。同じ勘を使うにもコツをつかめばめちゃくちゃ楽になるはずです。--abee
- きっとブラウジングの仕方あたりをどこかできっちりやらないととは思います。実はそれがabeeさんが伝えたいことだと勝手に推測してますが。まだソースコード自体に抵抗がある状態で、今現在まだまだそれになれるのにやっとの状態かも。この流れについていくためにはそれなりの覚悟が必要だと思ってまする。<罠に引っかかったようなので覚悟できてませんし公開でこの続きをやるにはおいら自体のキャパというか余裕がないかもです。中途半端になるのもいやだしabeeさんに失礼だし。おいら的にはやっと面白く思えてきてばかりの状態でする。はじめからあせってどうこうしようと思ってもいなかったのでマイペースでやりたいというのもあります。ま、ビシバシモードをいやがっているだけなのかにゃ。--thoru
Tuesday, 6 July 2004, 12:42:14 am
思うに、問題はStreamに慣れてないとかではなくって、オブジェクトとはなにかという本質のところだと思います。たぶん、インスタンスとクラスの違いも曖昧なのではないでしょうか。
では、streamは後回しにして、'***.cs'のクラスを教えてください。言葉通りです。--abee
- オブジェクトとは何かわかってないんだと思います。正直にかいてますよん。まさにインスタンスとクラスの区別がおいらはあいまいだとおもうです。<けっして開き直ってるんじゃないでする。物分りが悪いんでするよ。だから続行。--thoru
- abeeさんの質問に答えてなかった。'***.cs'のクラスはなにかですがわかりませんです。--thoru
Sunday, 4 July 2004, 7:03:26 pm
試してみたとこまでの経過報告でござる。
fileListでcsファイルを選んで、右クリックで出てくるメニューの「fileIn entire file」のハロを出しまして。
デバックハロのメニューから「inspect morph」を選んで、インスペクタを出して「target」を見ますると
Service: (FileStream --- fileIn:
とあるのでWorkspaceで試しますると
FileStream fileIn: '***.cs'
どうやら無事ファイル・インされたようなので(これだけでもおいら的にはゲッチュ!でした)
調子に乗って「ExternalDropHandler」で試してみますると
initializeに追加
registerHandler: self defaultCSHandler
メソッド追加
defaultCSHandler
^ ExternalDropHandler
type: nil
extension: 'cs'
action: [:stream | FileStream fileIn: stream]
ワールドにcsファイルをドロップ・インすると・・・・だめでした。
今日はここまでってことで。--thoru
- たぶんキモはここですね。ブロック引数streamに入っているオブジェクトのクラスはなんでしょうか。同じく'***.cs'のクラスはなんでしょう。--abee
- だめです。さっぱりわかりません。初めはstreamに入ってるのはFileStreamだと思ってたです。で、csのほうはDataStream。<ほとんど山勘。Stream関係は後回しにしてたのでさっぱりです。一応ちょっとずつ調べ始めてはいるのですが、Stream自体になれないと、やっぱ山勘たよりでする。defaultSARHandlerのfileInFromあたりからブラウズしてZipArchiveかな?とか。やっぱ、ここからはおいらにはハードル高すぎかも。でもあきらめてないっす。--thoru
ついでにcsファイルをネットからゲッチュの方法がわかってうれぴい。ScamperWorkspaceで使いたかったもんで。--thoru
HTTPSocket httpFileIn: 'URL'
Saturday, 3 July 2004, 5:18:54 pm
プロジェクトを読み込んでそのプロジェクト内でチェンジソータを開くとExternalDropHandler classってのがありますな。メソッドはdefaultSARHandlerとinitialize。これがabeeさんがこのプロジェクトで変更したやつかにゃ?でそいつをブラウズすると・・・ってかんじでいいのかにゃん。
initializeの
registerHandler: self defaultSARHandler
のかわりにcsを読み込むメソッドDdefaultCSHandler(勝手に名前付けちゃったけど)呼び出して
あとはそのメソッドを作るだけだと思うですがこれから先はまた調べなくちゃわかんないっすから、また後で。
SARInstallerクラスはあるんでそれつかえばいいんでしょうけど、csはどうかってのがこれから調べることやね。
- これをどう調べるかですね。どこをとっかかりにするか。--abee
ちなみにここでSmalltalkネタはいいんすか?--thoru
そうそうワールドをインスペクトすると「阿部 和広」の名前が踊ってますね(笑)--thoru
- みなさんも作品を公開するときは「詳細」ボタンで著者名を書きましょうね :-) --abee
Saturday, 3 July 2004, 3:09:18 am
なんちゃってビスケットてすか・・・。けっこういい味出てますね。入れ物ベースかあ・・・。ところで原田さんに教えてあげました?<でもSqueakは試しておられるのかなあ?お助けSARはうれしい一品でする。お助けシリーズをついつい期待してしまうおいら。--thoru
- 原田さんはSqueakを試されていると思います。「Squeakとの違い」というのも書かれてますし。もどきのことは掲示板にちょこっと書いてみたりしました。
お助けシリーズですが、目論見通りthoruさんが罠にかかったので、csファイルをドロップしたときはどう書くか考えてみたりしていただけますか。--abee
- 罠だったんですか?もうちょっと解りやすく仕掛けてくださいよ。そうすればさけられたのに。(笑)st、csファイルを読み込むってのは興味はあったのですが実際に調べてないのでこれを機に調べてみるです。でも他にも課題を抱えてるのでいつになることやら。ドロップ・インしたときどうなのかってことだからここらへんがabeeさんの罠のポイントぽいな。--thoru
- 罠の狙いは、いかに楽して見つけるかです。もっというとチェンジソータとブラウザの使い方です。--abee
Link to this Page
- SqueakToys掲示板2 last edited on 13 July 2012 at 8:01:48 pm by softbank219195146128.bbtec.net