LoginSignup
4
3

More than 5 years have passed since last update.

SmalltalkからScratchをいじる(5) ブロックの動作を調べる

Posted at

前回、SmalltalkのコードとScratchのブロックの対応をさせて説明しました。
add-list.png

リストの要素追加.st
100 timesRepeat:[
  (self owner isKindOf: HandMorph) ifTrue:[
    self append: self xpos toList: 'paths-x'.
    self append: self ypos toList: 'paths-y'
  ].
  (Delay forMilliseconds: 100) wait
]

「"x座標"を"paths-x"に追加する」というブロックが、3行目のself append: self xpos toList: 'paths-x'に対応します。
今回は、ブロックから対応するSmalltalkの処理を調べる方法を紹介します。

(Smalltalkを使えるようにする方法やハロの出し方等はこちらを参照)

レシーバとセレクタ

以降の手順を理解するためにレシーバセレクタという概念を理解する必要が有ります。ここでSmalltalkの文法を簡単に説明します。
Smalltalkはオブジェクトにメッセージを送ることでプログラムを記述します。レシーバ(receiver)はメッセージを受け取るオブジェクトで、セレクタ(selector)はメッセージの種類です。例えば、self xposというコードでは、レシーバはself、セレクタはxposになります。
セレクタの最後にコロン(:)が付いている場合、追加の情報を加えてメッセージを送ることもできます。Transcript show: 'recording...'というコードでは、Transcriptというオブジェクトにshow:というセレクタで、'recording...'という文字列を追加の情報として送っています。この追加の情報を引数(arguments)と言います。
セレクタに含まれるコロンの数だけ引数を渡します。append:toList:は2つの引数を渡すセレクタであり、self append: 100 toList: 'paths-x'というコードを書くと、selfというレシーバに対し100'paths-x'という引数を渡すことになります。
これまで、登場したSmalltalkのコードのレシーバ、セレクタは下記のようになります。

self xpos                           " → レシーバはself、セレクタはxpos、引数なし"
Transcript show: 'recording.'    " → レシーバはTranscript、セレクタはshow:、引数は'recording.'"
self append: 100 toList: 'paths-x'  " → レシーバはself、セレクタはappend:toList:、引数は100と'paths-x'"
(Delay forMilliseconds: 100) wait   " → レシーバは(Delay forMilliseconds: 100)、セレクタはwait"

手順

  1. リストに値を追加するブロックにハロを表示して、レンチアイコンからinspect morphを選択します。("CommandBlock"と表示されます)
    block.png

  2. インスペクタの画面上部左側の枠を少し下にスクロールさせて、"receiver"と"selector"の値を確認します。
    inspector.png

    "receiver"は"a ScratchSpriteMorph"、"selector"は"#append:toList:"と表示されるはずです。

  3. 手順2.で確認したブロックのオブジェクトが持っていたreceiverとselectorはブロックが実行されると、どのレシーバに対して、どのセレクタでメッセージを送るかの情報になります。今回の例ではスプライトのオブジェクト( ScratchSpriteMorphクラスのオブジェクト)に対して、```append:toList:"というセレクタでメッセージを送ることになります。

  4. 先程のappend:toList:のコードをシステムブラウザで見てみましょう。再度、"receiver"を選択してメニューを開き(Windowsの場合は右クリック、macはoption+クリック)、「browse full」を選択します(または、Alt/Command+b)。receiverのクラス(つまりScratchSpriteMorph)をシステムブラウザで開きます。
    menu.png

  5. 画面上部の右から2番目の枠の一番上の"-- all --"をクリックすると、一番右の枠にそのクラスが受け取れるセレクタの一覧が表示されます。
    all.png

  6. 下の方にxpos(X座標を調べる時に使った)などはありますが、append:toList:はありません。クラスに無いセレクタが呼ばれた場合、その親クラスのセレクタを探します。クラスの親子関係を継承関係と言います。
    selectors.png

  7. クラスの継承関係を調べます。左から2番目の枠でScratchSpriteMorphを選択した状態になっているはずです。そのメニューを開き(Windowsの場合は右クリック、macの場合はoption+クリック)、"browse hierarchy"を選択します。
    menu2.png

  8. 左側の枠に継承関係が表示されます。ScratchSpriteMorphの親はScriptableScratchMorphで、その親がMorph、さらにその親がObjectになっています。セレクタは一番下のクラスから順に親に向かって検索されます。append:toList:はScratchSpriteMorphにはないので、その親のScriptableScratchMorphにそのセレクタが定義されているかを調べます。
    hierarchy.png

  9. 左側の枠のScriptableScratchMorphをクリックして、真ん中の枠の"-- all --"をクリックすると、一番右の枠にappend:toList:が現れます。画面下部に表示されているコードがScratchSpriteMorphクラスのオブジェクトにappend:toList:を送った時に実行されます。

  10. 本当にブロックを実行するとこのコードが実行されるかを確認してみましょう。2行目にself halt.を追加してメニューからaccept(またはAlt/Command + s)します。
    accept.png

  11. ブロックをクリックして実行すると、赤いウィンドウが表示され、停止します。「debug」をクリックしてデバッガを起動します。
    notify.png

  12. デバッガの上段の枠の3つめをクリックします。先ほど追加したself halt.で停止しているはずです。デバッガの左下の枠から変数の値を確認することができます。
    debugger.png
    t1〜t3という変数があります。コードの一行めを見てみるとappend: t1 toList: t2となっています。つまり、self append: (値) toList: '(変数名)'というコードは最初の引数がt1に、二つ目がt2に入ることになります。

  13. 確認が終わったら、挿入したself halt.を削除してacceptして、元に戻します。

Smalltalk の学習のための資料

ここまででSmalltalkの基本的な概念やツールに触れてきましたが、自由にSmalltalkを扱えるようになるには一から理解を積み重ねることが大事です。
Smalltalkの教材はインターネット上にもいくつかありますが、Scratchを動かしているSmalltalkはかなり古いことに気をつけて下さい。見た目の違いや新しいSmalltalkにしかない機能があったりして戸惑うかもしれません。基本的な部分は同じなので、下記の資料が参考になるでしょう。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3