ワークスペースを拡張して Wiki 的機能を仕込む
ちょうど2ちゃんねるの Squeak/Smalltalk 関連スレで、こんなカキコがありましたから、これをやってみましょう。--sumim - 2002-12-16, 15:28:10
このほかにここまでで分からないこと、さらっておきたいこと、知りたいことがあれば上は気にせず挙げていただければさいわいです。--sumim - 2002-12-16, 15:37:52
今のところは大丈夫だと思います.分からない事や疑問に感じた事は,その都度ご質問させて頂くかもしれません.私が誤解してるっぽかったら,ビシッ!っと指摘しやってください.2ch,逝ってきます(汗)--人狼 - 2002-12-16, 15:46:23
了解しますた。<離れろ!(笑) では、ワークスペースの Wiki 化です。そうは言っても、リンクを作ってそれをクリックすると同名のワークスペースを開く、なければ作るってだけの簡単な仕様ですが演習問題にはいいと思います。まず、使えそうな部品(クラスやメソッド)を模索します。もっともワークスペースにはすでにハイパーリンクを作る機能(cmd-6)があるのでこれを流用しない手はないわけですが。--sumim - 2002-12-16, 15:53:17
まず、cmd-6 の機能を復習してみましょう。テキストを選択して、cmd-6 をタイプするとメニューが現われ、そこで色とハイパーリンク(メッセージ式と解釈して do-it もしくは print-it 。クラス名と解釈してそのコメント、定義式、クラス階層の表示。「クラス名 メッセージ」と解釈してそのメソッド表示、URL と解釈して WWW ブラウザの呼び出し)の指定の項目があります。あとオマケとして cmd-6 のハイパーリンクと同じしくみで動作する cmd-P のプロジェクト名として同名プロジェクトの呼び出し用ハイパーリンク作成機能があります。--sumim - 2002-12-16, 16:03:11
そうそう。プロジェクトで思い出しましたが、新しいプロジェクトを作成し、そのタイトルは WorkspaceWiki とでもしておきましょうか。--sumim - 2002-12-16, 16:04:51
>ワークスペースのWiki化です。
Wikiと言うと例の…と言うか,このWikiですよね.これをWEBページではなくて,Workspaceで実装する…と.
>これを流用しない手はない
えぇっと,cmd-6のbe a web URL linkを使うのでしょうか?--人狼 - 2002-12-16, 16:09:51
ワークスペースを開き、上述の機能がきちんと動作するか確認しておきます。まあ、ここいらへんは本末転倒的なところがあって、上の機能の使い方をどうやって調べたかっていうと、ここで説明する前にただ当該メソッドのソースを見てみただけって話が正直なところでして、そのとおりに動くのは当たり前っちゃあそれまでなのですが…(^_^;)。--sumim - 2002-12-16, 16:10:02
>新しいプロジェクトを作成し
準備OKです.--人狼 - 2002-12-16, 16:10:36
>cmd-6のbe a web URL linkを使うのでしょうか?
まあ、そういう流れになると思います。--sumim - 2002-12-16, 16:10:55
たとえば、http://www.apple.com/ とタイプし、これを選択して cmd-6 して be a web URL を選択すると淡い青色になってハイパーリンク化されます。これをクリックするとしょぼい WWW ブラウザが開いて HTML の解釈に失敗してソースが見えちゃったり、ヨーヨー・マさんの肩が分断されてたりしますけど、一応、WWW ページが現われます。これがどうやって実現されているかを解析してみましょう。--sumim - 2002-12-16, 16:15:10
防火壁の中だとアクセスできないかも。--sumim - 2002-12-16, 16:15:59
前にも取り上げましたが、メニューを表示する機能は、それを担当するクラスやメソッドを比較的簡単に捕まえることができます。cmd-6 で表示されるメニューのメニュー項目をモーフとして選択して、灰ハローからインスペクタを呼び出しましょう。サブモーフの選択は cmd-shift-クリックで、灰ハローからメニューを経由せずにインスペクタを呼び出すのも灰ハローの shift-クリックで一発でできます。--sumim - 2002-12-16, 16:23:14
インスペクタが表示されたら、以前と同じように target 、selector 、arguments を調べます。ところが、今回は具体的な情報は得られないようです。--sumim - 2002-12-16, 16:25:58
ところで人狼さんは MVC という言葉は聞いたことがありますか?--sumim - 2002-12-16, 16:29:45
>防火壁の中だとアクセスできないかも
残念ながら,だめっぽいです.家で試してみます.--人狼 - 2002-12-16, 16:29:53
>家で試してみます.
いえ。今はヨーヨー・マを呼び出すのは本質ではないので無視してください。--sumim - 2002-12-16, 16:32:15
>今回は具体的な情報は得られないよう
何やらMVCが大きく関係していそうですが,argumentsが謎だらけですね.#(16)と言われても(汗)--人狼 - 2002-12-16, 16:32:49
>MVCという言葉
Model-View-Contorllerの事でよろしいのでしょうか?ヨーヨー・マの件は了解です.--人狼 - 2002-12-16, 16:34:01
そうです。説明はいらなそうですね。昔の Smalltalk 環境は、この考え方で GUI が設計されていました。ほんとは逆で統一感を持つ GUI を設計するために考え出されたんですけど…。> MVC Mac UG っぽいネタに振るなら、この表層的な部分を整備して Apple の UI ガイドラインみたいな発想が生まれたわけです。--sumim - 2002-12-16, 16:39:20
>昔のSmalltalk環境は、この考え方でGUIが設計されていました
そうでしたか.MVCの「一つのモデルに多様なビューを与える事が出来る」と言う事で設計されていたと言うことでしょうか?結果として,UIが多種多様だったのでしょうか.話しの本質には関係ないですね.すみません.--人狼 - 2002-12-16, 16:44:40
ああ、そう。“多様”は多様なんですが、共通のウィジェットを使ってひとつのモデルについて多様な表現や編集の方法が比較的簡単に実装できる…ということですね。共通のウィジェットを使うので使用感が統一できると。そんな話です。そう望まないときにも似たような見栄えの GUI になってしまうというのを欠点に挙げる人もいます。--sumim - 2002-12-16, 16:54:51
モデルについては、ビュー(自分の見せ方)やコントローラ(ユーザーからの操作・編集の具体的手段)を意識せずに文字通りモデルとしての作り込みができ、一方で、ビューやコントローラはいろいろな方法論でユーザーにモデルへの接し方を提供できる…と言ったデータ本体とその操作系の分離によるメリットを追求する考え方です。--sumim - 2002-12-16, 17:06:54
>共通のウィジェットを使ってひとつのモデルについて多様な表現や編集の方法が比較的簡単に実装できる
なるほど,了解しました.有り難うございます.--人狼 - 2002-12-16, 17:07:18
>データ本体とその操作系の分離によるメリットを追求
OKです.MVCの求めるところですね.--人狼 - 2002-12-16, 17:09:12
これに対して、モーフは自分の見せ方や操作方法も継承もしくはオーバーライドすることで自分で持っています(クラスに定義されている)ので、MVC とは逆の考え方、ある意味、UI 分離を目指した MVC からまた元に戻ったともいえる設計になっています。--sumim - 2002-12-16, 17:11:05
>UI分離を目指したMVCからまた元に戻った
確かにそうですね.なぜ,MVCから元に戻るような事をしたのでしょう?--人狼 - 2002-12-16, 17:14:59
かつての Smalltalk の MVC ベースの UI も Squeak には残されていて、いまも使うことができます。デスクトップメニューから open... → mvc project で切り換えることができます。昔、Morphic はこの MVC フレームワークで実装され、今はもはや MVC ベースの GUI に頼ることなく、自分の GUI の中に各種ツールを利用できるようにして自らにおいて自らの開発ができるようになったわけです。ある意味、すごいことですよね。--sumim - 2002-12-16, 17:18:37
>なぜ,MVCから元に戻るような事をしたのでしょう?
詳しくは分かりませんが、Morphic フレームワークが当初、Self で実装されたものであることと関係があるかもしれません。--sumim - 2002-12-16, 17:21:41
>自分のGUIの中に各種ツールを利用できるようにして自らにおいて自らの開発ができる
すごいことですね.技術屋っぽくない,ただの感想ですが,非常に有機的と言うか生物敵的な感じがします.わけわからんすね.すみません.--人狼 - 2002-12-16, 17:25:26
>当初、Selfで実装されたものであることと関係があるかも
浅学にして,Selfと言うものがよくわかっていないので,今度機会があれば調べてみます.とりあえず,今の話題とは直接にはかかわらない事なので,おいておきます.--人狼 - 2002-12-16, 17:26:58
そうですね。まさに生物的です。--sumim - 2002-12-16, 17:27:09
うぅ.すみません.「生物敵」×→「生物的」○と言う事で--人狼 - 2002-12-16, 17:27:53
ひとつ前に出てきた Pluggable なんたら という考え方も MVC 関係です。私の理解ではビューやコントローラにより汎用性を持たせようという試みだったと思います。メニューを表示するのにもメニューを表示するためのしくみだけ用意しておいてメニューの内容やその項目を選択したときに何をするかはモデル任せにする…というものです。前の PluggableTextMorph のインスタンスを作るとき、モデルの他にいろいろなシンボルを引数として与えていたのを覚えておられるでしょうか。あれは、モデルに対してメニューを要求したり、モデルの把握している(accept した)データを引き出したり(cancel)、モデルに、今の自分の状態を把握させる(accept)するためにどんなメッセージを送るのか…ということをインスタンスに登録する作業をあの長いメッセージでやっているわけです。--sumim - 2002-12-16, 17:34:09
>「生物敵」×→「生物的」○
ああ。そういうのは Wiki ですからあとで(書き換えがまばらなときに)こそっと直してしまってください(笑)。--sumim - 2002-12-16, 17:35:04
で、なんでモーフなのに Pluggable つまり MVC なのか…ってことなんですが、まず、ブラウザやワークスペースなどの主要なツールが MVC ベースの UI で組まれたものの移植だという背景に留意する必要があります。--sumim - 2002-12-16, 17:43:18
>ビューやコントローラにより汎用性を持たせよう
なるほど.メニューの例は分かりやすいです.確かにモデルが分離されていますね.PluggableTextMorphのインスタンスの作成の時は,流していたあの長いメッセージには,そう言う意味があったのですね.--人狼 - 2002-12-16, 17:45:22
cmd-6 もそうで、mvc project でもまったく同じように操作ができます。--sumim - 2002-12-16, 17:45:52
>こそっと直して
さっき直そうとしてコンフリクトしたので,少しびびってました.今回は無事に直せたようです.--人狼 - 2002-12-16, 17:46:52
>ブラウザやワークスペースなどの主要なツールがMVCベースのUIで組まれたものの移植
了解です.この背景を忘れると,訳が分からなくなりそうです.モーフとMVCが混在しているのですね.気を付けないと.--人狼 - 2002-12-16, 17:48:27
mvc project をいじってみると、cmd-6 に限らず、デスクトップメニューやそのサブメニュー、ウインドウ(MVC ではビューですが)内で表示される黄ボタンメニューの内容もほぼ同じものだということに気付かれると思います。--sumim - 2002-12-16, 17:49:40
>cmd-6 もそうで
おぉ.確かに.最初,Workspaceをどこから出すのか少し悩んだのは内緒にしといてください(苦笑)--人狼 - 2002-12-16, 17:54:05
>ほぼ同じものだということ
はい,細かく見ていけば,違うのかも知れませんが,ほぼ同じですね.違和感がありません.--人狼 - 2002-12-16, 17:54:44
実は、Morphic ベースの GUI で使われているメニューのほとんどは、この MVC ベースで構築されたオブジェクトで定義されたメニュー項目を流用(横取り)しています。横取りのしかたが2通りあって、選択したときに返されるシンボル(主にそのメニューコマンドを実行するためのメッセージセレクタ)まで使って、target と selector、argumnet つまりメッセージ式の構成要素をメニュー項目のなかに封じ込めてしまう方法と、元のメニューからはメニュー項目の文字列だけ得て、ユーザーが選択した項目の ID(上からの順番)だけを返すもの、です。この cmd-6 のメニューでは後者だったので、具体的な情報が含まれていなかったわけです。これは、cmd-6 のメニュー項目の選択がおのおのメソッドに分割されておらず、cmd-6 専用のひとつのメソッド内で選択されたメニュー項目によって処理を分岐して実行していることを示唆します。つまりメッセージ式で表現しようとしてもできないのでこうしたのではないでしょうか。--sumim - 2002-12-16, 18:15:11
>最初,Workspaceをどこから出すのか少し悩んだ
そうですね。フラップからの方法しか説明していませんでしたもんね(^_^;)。--sumim - 2002-12-16, 18:19:01
体調不良の為,本日はお休みさせて下さい.すみません.--人狼 - 2002-12-17, 09:41:54
お大事に。--sumim - 2002-12-17, 11:27:36
復活…かな?--人狼 - 2002-12-18, 09:27:53
>横取りのしかたが2通り
なるほど,それでtarget,selector,argumentsがこんなにも違うのですね.cmd-6についても了解です.確かに16番目でした.--人狼 - 2002-12-18, 09:30:14
ご復活、なによりです。私も(も?)AC04、気を取り直して復活し、昨夜 NORMAL を F-16C でクリアしました。最後のロケットが被弾しても爆発しないのでミサイルを変えたり、撃つタイミングを変えたり試行錯誤しましたが、結局駄目で、じゃあ、とりあえず脇をすり抜けてあとで上から攻撃しようか、なんて思ったら……クリアでした。なんだ最初の何回目かでクリアできてたんじゃん…とまた鬱になりました(笑)。とりあえずお勧めの X-02 がどのくらい強力なのか見てみたい(己を知れど敵を知らずんば一勝一負す)ので全ミッションSランクとるべく2周目中です。--sumim - 2002-12-18, 10:54:28
>昨夜NORMALをF-16Cでクリア
おぉっ.おめでとうございます.
>最後のロケットが被弾しても爆発しない
えっと,最後の面のターゲットはジェネレータ×3と,ミサイル×4ですよね.クリアはされていると言う事ですので,ジェネレータは大丈夫ですよね.ミサイル×4は打ち上げ前にこちらがミサイルをあてなくちゃいけません.
>とりあえずお勧めの X-02
お勧めじゃないっす.私がsumimさんと対戦する時の使用予定機材です(汗)これをsumimさんに使われたら勝ち目無いっす.--人狼 - 2002-12-18, 11:09:13
MVC でメニュー出すのには PopUpMenu 、SelectionMenu 、CustomMenu というのを使っていました。たとえば、PopUpMenu では PopUpMenu class >> #labelArray:lines: に(PopUpMenu labelArray: #('frog' 'and' 'toad') lines: #()) startUp
のような使用例がコメントアウト状態で呈示されています。example というメソッドを用意して明示的に使用法を示す方がよいのですが、多くの場合そうはなっておらず、こうしてコメントとして使用例を示すに留められています。が、これでもないよりはマシです(笑)。--sumim - 2002-12-18, 11:09:22
これを mvc project と morphic project(普通の画面)の両方で試してみていただけますか?--sumim - 2002-12-18, 11:12:28
>コメントアウト状態で呈示
確認しました.コメントとは言え,手がかりがあるだけマシですね.--人狼 - 2002-12-18, 12:21:31
>試してみて
やってみました.メニューの形状は(当然)異なるものの,メニューは表示されました.--人狼 - 2002-12-18, 12:22:10
>メニューの形状は(当然)異なる
なぜ“当然”と思われましたか? そもそもなぜ Mophic フレームワークでこの古いフレームワーク向けのクラスが機能するのかについてはあまり気になりませんでしたか? なお、トラップとはぜんぜん関係ありませんが、print-it すると、選択した文字列 項目番号が返ってきているのが分かりますのでこちらも試してみてください。--sumim - 2002-12-18, 12:55:41
>なぜ“当然”と思われましたか?
デスクトップメニュー等のメニューの形状が,元々異なっていましたので,そう考えました.先にメニュー表示の実例を見ているので,そう思ったと言う事で,MVCとMorphicで異なっているのが当然との主旨ではありませんでした.--人狼 - 2002-12-18, 13:06:33
>そもそもなぜMophicフレームワークでこの古いフレームワーク向けのクラスが機能するのか
主要なツールがMVCからMorphicに移植されて来たと言う歴史がその理由だと思っていました.--人狼 - 2002-12-18, 13:09:50
>選択した文字列が返ってきている
あれ?私のところではPopupが表示されて,そこで選択したメニューの番号が返ってきてます.--人狼 - 2002-12-18, 13:12:07
>メニューの番号が返ってきてます
ああ。そうでした。ごめんなさい。--sumim - 2002-12-18, 13:22:10
>主要なツールがMVCからMorphicに移植されて来たと言う歴史
なるほど。それなら疑問でもなんでもありませんね(^_^;)。このことは具体的には PopUpMenu >> #startUpWithCaption:at:allowKeyboard: のメソッドで確認できます。Smalltalk isMorphic とするとこで、今、Moprhic フレームワークにいるかどうかを判断し、そうならば、メニューを MVCMenuMoprh を使って改めて Morphic 用に再構成する作業をしています。--sumim - 2002-12-18, 13:31:24
>Moprhicフレームワークにいるかどうかを判断し
なるほど.メソッドの中を見ると確かにそうですね.MVCとMorphicで,それぞれSmalltalk isMorphicを確認しました.--人狼 - 2002-12-18, 14:07:00
>MVCとMorphicで,それぞれ
あ、いや、それは同じものを見ています。GUI フレームワークが違うだけで、両者でのブラウザは同じ働きをします。コマンドラインでも見てもファインダでも見ても、フォルダ(ディレクトリ)の中身は同じ…というのと似ています。--sumim - 2002-12-18, 14:15:47
>両者でのブラウザは同じ働きを
あ,私の申し上げ方がまずかったです,済みません(汗)MVCとMorphicそれぞれで,WorkspaceにおいてSmalltalk isMorphicをprint-itして,それぞれfalseとtrueになる事を確認いたしました.--人狼 - 2002-12-18, 14:29:31
前の“メソッド”がトリガーになって、“それぞれ”の後に に を脳内挿入してしまっていました。ごめんなさい(^_^;)。--sumim - 2002-12-18, 14:33:06
先の例で、(PopUpMenu labelArray: #('frog' 'and' 'toad') lines: #(2)) startUp
のように labelArray:lines: の二番目の引数の配列にメニュー項目番号を要素として追加すると、その項目の直後に区切り線を入れられます。--sumim - 2002-12-18, 15:00:14
>前の“メソッド”がトリガーになって
すみません,私の発言が不用意でした(汗)--人狼 - 2002-12-18, 15:04:54
他方、SelectionMenu と CustomMenu は PopUpMenu のサブクラスで、選択したときに項目番号ではなく、あらかじめ項目割り振ってあったシンボルを返します。CustomMenu は SelectionMenu と一緒ですが、もっとオブジェクトっぽく(つまりメニュー項目や区切り線の追加をインスタンスに対するメッセージの送信のかたちでできるように)したててあります。SelectionMenu に関しては使い方のサンプルが Selection class >> ##fromArray: にあります。これはメニュー項目とそれを選択したときに返すシンボルのペアの配列を要素に持つ配列を引数に添えて送信しています。(SelectionMenu fromArray:
#(('first label' moja)
('second label' mbili)
-
('third label' tatu)
-
('fourth label' nne)
('fifth label' tano))) startUp
区切り線の位置も #- で指定されています。ちなみに、要素がすべてリテラルの場合、#() で配列を記述できる話は前にしましたが、このとき、シンボルと配列に関しては先頭の # を省略することができます。したがってこれは(SelectionMenu fromArray:
#(#('first label' #moja)
#('second label' #mbili)
#-
#('third label' #tatu)
#-
#('fourth label' #nne)
#('fifth label' #tano))) startUp
と同じです。print-it すると、こんどは数字の代わりに対応するシンボルが返ってくるはずです。--sumim - 2002-12-18, 15:06:14
>その項目の直後に区切り線
はい,確認できました.項目番号を#(1,2)のようにすると,複数の区切り線を引く事が出来ましたが,これはやって構わない事だったのかな.この時の#(1,2)は配列になるのでしょうか?--人狼 - 2002-12-18, 15:08:20
>項目番号を#(1,2)のようにすると
それはやってもかまいませんが、書き方がちょっと…(^_^;)。#() で配列を記述するときは、要素を スペース で区切ります。ちなみに #(1,2) を print-it(inspect-it のほうがよいかも…)していただけると分かるように、これは #(1 #, 2) という3要素(数値の 1、2 にシンボルのカンマを加えたもの)の配列として解釈されます。なお、この情報を参照する区切り線を入れるための処理では引数として与えられた配列内に、その項目番号が含まれているかどうかだけをチェックしているのでエラーにはなりませんでした。--sumim - 2002-12-18, 15:13:24
>SelectionMenuに関しては使い方のサンプル
試してみました.#を省略したりとか,いろいろ.なるほどです.print-itすると,#を省略していても#mbili等と#を付けて表示されますね.--人狼 - 2002-12-18, 15:41:20
>要素をスペースで区切ります
すみません,その通りでした.--人狼 - 2002-12-18, 15:42:13
>#を付けて表示されます
そうですね。Symbol >> #storeOn: にそんなようなことが書いてあります。配列リテラル式の括弧内で # を省略してもこれがシンボルとしてきちんと認識されていることの証でしょう。--sumim - 2002-12-18, 16:05:44
今回のように単に do-it 、pirnt-it したときと違い、オブジェクトのメソッド内で用いられるときは、おそらくほとんどの場合、返ってきたシンボルをメッセージとして自分自身に送るようなしくみが施されていることが予想されます。Morphic フレームワークへの移植の際には、この仕組みを利用して、MenuItemMorph の target、selector、argumets を決めているのだと思います。MenuMorph をいちから作っている場合も、こうして SelectionMenu を焼き直した場合も、その MenuItemMorph のインスタンス変数から、何をしようとしているかを予想できるのですが、cmd-6 のメニューモーフではそれができない…という話に戻りたいと思います。--sumim - 2002-12-18, 16:25:34
このように MVCMenuMorph でメニューができていて、そのメニュー項目モーフから情報が得られないときは、しかたがないので、元のメニューを出しているメソッドを当たるしかありません。メソッドのメッセージセレクタが分からないときは、その内容から検索します。メニューを作る場合、そのメニュー項目は大抵、文字列リテラルとしてメソッド中に記述するはずなので、特定の文字列を含む文字列リテラルが記述されたメソッドを検索する method string with it を使いましょう。choose color... をどこかにタイプして選択し、cmd-E とします(もしくはシフト黄ボタンメニューから同名のメニュー項目を選びます)。すると条件に当てはまるメソッドが2つ見つかります。うち、ParagraphEditor >> #changeEmphasis: が“当たり”のようです。--sumim - 2002-12-18, 16:33:31
ただ、確証はないので本当に cmd-6 したときに現われるメニューがこのメソッドによって作られているのかどうかを念のため確認しておきましょう。| | で括られた一時変数宣言の直後に self halt. とタイプして accept してみてください。cmd-6 をタイプしたときにノーティファイアが現われれば、目論み通りとなります。--sumim - 2002-12-18, 16:38:08
>シンボルとしてきちんと認識されていることの証
そうですね,そう言う事になりますよね.--人狼 - 2002-12-18, 16:44:00
ここで、halt というメッセージのメソッドは Object に定義されているので、self とすることにはあまり意味はありません。--sumim - 2002-12-18, 16:44:10
>返ってきたシンボルをメッセージとして自分自身に送るようなしくみが施されていることが予想
そうですね,そのような仕組みになっていそうですね.そう言う仕組みしないと「で,返ってきたシンボルをどうするの?」と言う話しになってしまいそうです.--人狼 - 2002-12-18, 17:02:38
>元のメニューを出しているメソッドを当たる
なるほど.method string with itはこうやって使うのですね.二つ程度でしたら,メソッドの中を見て当たりかどうか判断出来ますが,10もあったら大変そうですね.--人狼 - 2002-12-18, 17:06:47
>ノーティファイアが現われれば
確かにHaltと言うタイトルのノーティファイアが表示され,ParagraphEditor >> #changeEmphasisからObject >> #haltが呼び出されている事が判りました.--人狼 - 2002-12-18, 17:09:40
>selfとすることにはあまり意味はありません
とは言うものの,selfと書かずにacceptしようとしても「知らない変数だよ」と怒られてしまいますよね.--人狼 - 2002-12-18, 17:10:48
>「知らない変数だよ」と怒られてしまいます
もちろん使える(偽)変数かリテラル、つまり参照可能なオブジェクトにしておく必要があります。あくまで受信者はオブジェクトでなければいけません。どうしても任意の文字列を使いたければ一時変数を定義すればよいのですが、たんなる割り込みをするのにそこまでこだわる必然性もなさそうな気も…(^_^;)。ちなみにそれ用に一時変数をしたてた場合でも、結局はそこに束縛されている nil に halt を送ったのと同義になります。--sumim - 2002-12-18, 17:17:23
>10もあったら大変そう
それは検索に使うキーが悪いのではないかと…。実はこの choose color... もあまりよいキーとは言えません Link to method などとすれば、一意に決められます。--sumim - 2002-12-18, 17:21:55
>受信者はオブジェクトでなければいけません
そうですよね.メッセージですものね.アホだ>自分.
>結局はそこに束縛されている nilにhaltを送ったのと同義
つまりは,そのメソッド内で参照可能なオブジェクトであれば,何でも良いと言う事ですよね.--人狼 - 2002-12-18, 17:24:09 赤字はsumimの追記
そうです。--sumim - 2002-12-18, 17:26:06
>それは検索に使うキーが悪いのでは
確かにそうですね(大汗)--人狼 - 2002-12-18, 17:27:49
せっかくノーティファイアを出したので、デバッガをやってしまいましょう。ノーティファイアはこのように任意のオブジェクトに halt を送るか、cmd-ピリオドでいつでも呼び出すことができます。ここに列挙されているのは、コンテキストと呼ばれる「インタプリタの内部状態」の履歴(正確にはスタックの状況)を示すものです。Smalltalk はバイトコードと呼ばれる中間言語をインタープリタが逐次翻訳して動作しています。バイトコードにはいわゆる goto 文とかあったりしてそれはそれで楽しめます。ま、それは置いておいて、そのバイトコードを実行中に、別のメソッドを起動しなければならないとき(つまりメソッド中にメッセージ式が記述されている場合。ほとんどのメソッドがそうですね)に、いったん自分の状態(コンテキスト)をスタックして新しいメソッドを実行しようとします。このスタックの状態、つまり halt されたときのコンテキストに至る履歴がノーティファイアに表示されているわけです。具体的には、どんなオブジェクトがどのクラスに定義されているどのメソッドを起動したのか…ということが過去に遡るかたちで書き記されているわけです。どれかをクリックするとデバッガが起動します。ここでは、2番目のものをクリックしましょう。--sumim - 2002-12-18, 17:37:50
ちなみにノーティファイアで Proceed は、self halt. などで強制的にノーティファイアを出したときに有効で、その割り込みを無視して作業を続行するとき、Abandon はノーティファイアを閉じて処理も続けないとき(クローズボックスも同じ)、Debug はコンテクストの指定なしにデバッガを起動するとき、に使います。--sumim - 2002-12-18, 17:45:32
デバッガの一番上のペインは、ノーティファイアの内容と一緒です。クリックすると、そのコンテキストの内容を下に表示します。2番目のペインは、駆動中のバイトコード(メソッド)のソースを示します。一番下の左手の2つのペインはレシーバのインスペクタ、右手の2つはコンテキスト自身のインスペクタ(見やすいようにちょっとモディファイされていますが…)です。実用上前者はレシーバ自身やそのインスタンス変数に束縛されているオブジェクトについて知りたいとき、後者は一時変数に束縛されているオブジェクトについて知りたいときに使います。もちろん、インスペクタと同様に別のオブジェクトを束縛し直すこともできます。--sumim - 2002-12-18, 17:47:15
そう。Smalltalk では「インタプリタの内部状態」すらもオブジェクトなのです。--sumim - 2002-12-18, 17:48:00
>デバッガをやってしまいましょう
おぉっ.ついにデバッガですね.どきどき.
>どんなオブジェクトがどのクラスに定義されているどのメソッドを起動したのか
スタックリスト+コールヒストリみたいなものですね.--人狼 - 2002-12-18, 23:03:14
デバッガの各ペインについては了解です.
>別のオブジェクトを束縛し直すことも
これは,テキスト(として表示されている内容)を編集してacceptすれば良いと言うことですね?
>「インタプリタの内部状態」すらもオブジェクト
これが,コンテキスト(=右のペインに表示されている)ものなんですよね.ここまでオブジェクトと言うのは,いやはや.驚きです.インタプリタの内部状態と言うのは別にデバッグ時でなくともオブジェクトとして,参照される事はあるのでしょうか?--人狼 - 2002-12-18, 23:08:39
>これは,テキスト(として表示されている内容)を編集してacceptすれば良いと言うことですね?
インスペクタの右ペインと一緒で、かならずしもテキストの編集でいけるとは限りません。右ペインで accept できるのはあくまで参照可能な(偽)変数かリテラル、もしくは束縛したいオブジェクトを返すメッセージ式を記入しなければいけません。--sumim - 2002-12-19, 10:06:15
あと、変数へのオブジェクトの束縛状況だけでなく、中央のコードペインの内容は、通常のブラウザと同様に編集して accept が可能なのでメソッドをその場で修正して再実行することも可能です。--sumim - 2002-12-19, 10:07:47
>デバッグ時でなくともオブジェクトとして,参照される事はあるのでしょうか?
さあ、どうでしょう。動的な(例えばセンダー依存的、つまりどのクラスのメソッドが駆動したかによって挙動を変える)メソッドを組むときくらいしか思い付きませんが。私は遊びで自らのソースを引っ張ってきてこねくり回すタイプのメソッドを組んだときに使ったことがあります。--sumim - 2002-12-19, 10:12:53
>参照可能な(偽)変数かリテラル、もしくは束縛したいオブジェクトを返すメッセージ式
なるほど,了解しました.--人狼 - 2002-12-19, 10:16:42
>メソッドをその場で修正して再実行する
これは,デバッグ時には大変有効なものですね.--人狼 - 2002-12-19, 10:17:31
>動的なメソッドを組むときくらいしか
なるほど.ごく当たり前に「インタプリタの内部状態」をオブジェクトとして参照すると言う事ではない,と言う事ですね.有り難うございます.--人狼 - 2002-12-19, 10:18:57
「インタープリタの内部状態」と言いましたが、そのソースがメソッドの“静的な側面”なのに対して、コンテキストはメソッドの“動的な側面”ととることもできます。ちなみにメソッドもオブジェクトなのは言うまでもないことですが、これまでよく利用していた PopUpMenu class >> #labelArray:lines: という表現も実はメッセージ式になっていて、inspect-it するとコンパイルされたメソッドを見ることができます。また、このオブジェクトにたとえば getSourceFromFile というメッセージを送ればそのソースを、symbolic と送ればバイトコードでどう記述されているのかを見ることができます。--sumim - 2002-12-19, 10:24:11
>ソースがメソッドの“静的な側面”なのに対して、コンテキストはメソッドの“動的な側面”
う〜ん,そう考える事も出来ますね,確かに.なるほど.
>メソッドもオブジェクト
でしたか!
>コンパイルされたメソッドを見る
CompiledMethodと言うタイトルでインスペクタが開きますね.中にはselfとall inst varsと1〜83の数が並んでいます.よくわからん(汗)
バ,バイトコードはわけわからんす.アセンブラみたい.--人狼 - 2002-12-19, 10:39:44
デバッガに戻って、中央のボタン群はデバッグ作業に使用します。主に使用するのは Send 、Step 、Through です。いずれも中断しているメソッドをステップごとに実行するのに使うのですが若干挙動が異なります。Send はメソッドを起動する記述(メッセージ式)があると、その内容もトレース(実行のシミュレート)をしようとします。スタックはどんどん積まれてゆきます。もちろん行き着けばまた戻ってきます。Step は逆で、現在のコンテキストを可能ならば抜けて、それを呼び出したコンテキストに戻るようにトレースします。Through は Step と同じですが、ブロックをレシーバとするメッセージ式の場合、その中には入ってゆく、という点で違います。雑な言い方をすると、大まかな流れを追いたいときは Step を、ブロック内も含めて見ておきたいときは Through を、詳細に追いたいときは Send を使う感じでしょうか。--sumim - 2002-12-19, 11:19:29
デバッガについてはこんなところでしょうか。self halt. は、削除して accept したりせず、メソッドの履歴を開いて(デバッガのスタックリストのペインなどで cmd-v )、self halt. を挿入する直前のバージョンに戻し(revert)ます。remove from changes しておくのも忘れないようにしましょう。--sumim - 2002-12-19, 11:27:03
>Sendはメソッドを起動する記述(メッセージ式)があると、その内容もトレース
これは,メソッド内を1ステップ(と言ってよいかどうか)実行して,メッセージ式ではその内容まで潜るのですよね.
>Stepは逆で、現在のコンテキストを可能ならば抜けて、それを呼び出したコンテキストに戻るようにトレースします
これも1ステップ実行するけど潜らないのでしょうか.
>ThroughはStepと同じですが、ブロックをレシーバとするメッセージ式の場合、その中には入ってゆく
了解しました.--人狼 - 2002-12-19, 11:35:03
さて、この ParagraphEditor >> #changeEmpahsis: ですが、cmd-6 だけでなく、cmd-1〜9、0、-、+ をタイプしたときに起動されるメソッドのようだということがkeyCode _ ('0123456789-=' indexOf: sensor keyboard ifAbsent: [1]) - 1.
とそれに続く数行から感じ取ることができます。すでに self halt. は取り去ってしまいましたが、残っていれば、cmd-6 だけでなく、cmd-1 などでもノーティファイアが出ます。--sumim - 2002-12-19, 11:38:36
>1ステップ実行するけど潜らない
そうですね。そういうふうに言った方が分かりやすいかもしれませんね。--sumim - 2002-12-19, 11:40:10
>デバッガのスタックリストのペインなどで cmd-v
あれれ?Error: key not foundと言うノーティファイアが出てしまいます.と,言う事で前と同じくcmd-Eでたどりました.
>remove from changes しておく
私のイニシャルが入る直前の物を選択して,revertしました.remove from changesは,私のイニシャルが付いている物に対してボタンを押しているのですが,何も変わりません(汗)--人狼 - 2002-12-19, 11:40:40
では、cmd-6 を押したときの処理は、というと、keyCode = 6 ifTrue: の引数になっているブロック内ということになりそうです。ifTrue: の直後の [ の右側にキャレットを置いてそれをクリックすると、当該処理全体を選択することができます。--sumim - 2002-12-19, 11:43:03
>あれれ?Error: key not foundと言うノーティファイアが出てしまいます
デバッガ(のコンテキスト)が持っているメソッドはコピーなので、そのメソッドを修正するタイミング如何ではデバッガ経由ではその履歴を呼び出すことはできないかも知れません。--sumim - 2002-12-19, 11:45:17
>remove from changesは,私のイニシャルが付いている物に対してボタンを押しているのですが,何も変わりません(汗)
remove from changes はチェンジとチェンジセットから「そのメソッドに修正がくわえられましたよ」という情報を削除する機能なので、メソッドの履歴自体には影響をあたえません。--sumim - 2002-12-19, 11:47:09
>それに続く数行から感じ取ること
はい,これは大丈夫です.そんな感じはします.--人狼 - 2002-12-19, 11:54:31
cmd-6 のときの処理を見ると、たしかに PopUpMenu を作ってそれを表示、返ってきたインデックスからさらになにか処理を施している様子をうかがうことができます。ここでは、be a web URL link を選択したとき、つまり index が 16、この場合、index _ index - colors size - 1. "Re-number!!!" でリナンバリングされているので実際には 7 のときに何をしているかに注目してみましょう。--sumim - 2002-12-19, 11:55:44
>keyCode = 6 ifTrue:の引数になっているブロック内
はい,これもOKです.選択もOKです.--人狼 - 2002-12-19, 11:57:31
>そのメソッドを修正するタイミング如何ではデバッガ経由ではその履歴を呼び出すことはできないかも
了解です.デバッガのコンテキストはメソッドのコピーを持っているんですね.--人狼 - 2002-12-19, 11:58:41
>チェンジとチェンジセットから
そうでした.失礼しました.--人狼 - 2002-12-19, 11:59:13
>cmd-6 のときの処理を見ると
確かにPopUpMenuから返却されたindexを使っていますね.ここでcolors sizeとあるのは,色の名前を格納した配列colorsの要素数でしょうか.さらに1を減じているのはchoose color...の分ですね.で,8+1の9を減じるので,indexが7の時と言う事になるのですね.--人狼 - 2002-12-19, 12:20:59
該当するコードはattribute _ TextURL new.
thisSel _ attribute analyze: self selection asString
の2行ですね。thisSel への代入は後の処理のためのもののようなので、要点は TextURL のインスタンスを作って、それに analyze: というメッセージを送っていることのようです。では、この TextURL はどんなことをするオブジェクトなのでしょう。browse-it してみてみましょう。--sumim - 2002-12-19, 12:24:13
どういう仕組みかは分かりませんが(^_^;)、クリックすると何かしらのアクションを起こすタイプのテキスト属性を実現するためのクラスのようです。先の analysis: が何をしているか確認してみましょう。--sumim - 2002-12-19, 12:34:35
>該当するコード
1行目はattributeと言う一時変数に新しく作ったTextURLのインスタンスを束縛している.
2行目はthisSelと言う一時変数に,attributeのanalyze:と言うセレクタを現在選択されているテキストを文字列オブジェクトとした物を引数に取って呼び出した結果のオブジェクトを束縛している.
と,言う事なのかな.2行目の説明が長くなってしまいました.ところで,この時のselfはParagraphEditorですよね.さきほど,メソッドもオブジェクトとおっしゃっていたので,ちょっと不安になりました.
TextURLはbrowse-itしました.--人狼 - 2002-12-19, 12:35:16
analyze: aString
| list |
list _ super analyze: aString.
url _ list at: 1.
^ list at: 2
TextAction の analysis: を使って得たリストの最初の要素を url とし、次の要素をメソッドの返値として返しているようです。では、TextAction の analysis: とは何をするメソッドなのでしょうか。ブラウザの inheritance ボタンを押して確認します。--sumim - 2002-12-19, 12:37:33
>先の analysis: が何をしているか確認してみましょう
analyze:はsuper analyze:を呼び出していますので,TextActionを見なくてはなりませんね.--人狼 - 2002-12-19, 12:37:54
>この時のselfはParagraphEditorですよね
self と super は常にメッセージのレシーバ(そのメソッドを駆動するメッセージ式において、メッセージを受けるオブジェクト)ですので安心してください。ちなみにメソッド中で実行時のメソッド(正確にはコンテキスト)を参照したいときは thisContext という偽変数を使います。--sumim - 2002-12-19, 12:41:42
>得たリストの最初の要素をurlとし、次の要素をメソッドの返値とし
えっと,ここで言うリストとはいわゆる普通のリスト(つまりデータ構造としてのリスト)と言うことでしょうか?
>ブラウザのinheritanceボタンを押して
準備OKです.--人狼 - 2002-12-19, 12:44:53
>selfとsuperは常にメッセージのレシーバ
了解です.安心しました.
>thisContextという偽変数
こちらも了解です.有り難うございます.--人狼 - 2002-12-19, 12:46:23
今さらながら,私がsumimさんの発言を引用する時は該当個所の色を変えた方がみやすいなぁ.何かお好みの色もありますか?後から参照する為に,昔のも遡って直そうかなぁ.--人狼 - 2002-12-19, 12:49:23
TextAction >> #analysis: は長いのですが、コメントなどを読みつつ解釈すると、文字列に < > で括られた情報があればそれを抽出して、なければ元の文字列自身をそれとして、配列のひとつめの要素にする。ふたつめの要素には < > で括られた情報を入れ、その配列を返す…というようなことをやっているようです。ふつうに URL を指定した場合は両者に同じものが入り、URL を < > で括って前か後に適当な文字列を入れれば、エイリアスとして使えるということですね。では実際にそうなっているか、試してみましょう。Apple<http://www.apple.com/> と入力して選択し、cmd-6 → be a web URL link すると、URL は消えて、Apple のみになります。今は試せないと思いますが、これをクリックすると隠された URL にアクセスに行くはずです。--sumim - 2002-12-19, 12:52:53
>何かお好みの色もありますか?
私は <i><font color=dimgray>></font></i> みたいなのをクリッピングしておいて、その都度ドラッグ&ドロップして>以降にコピペしています。black に対して dimgray なので、maroon に対しては brown か chocolate 、peru なんかがいいかもしれませんね。お任せします。ただあんまし凝ってしまうと、タグの閉じ忘れのチェックが大変になってぞっとしないかなとも(^_^;)。--sumim - 2002-12-19, 13:01:46
>コメントなどを読みつつ解釈すると
言われて読んでみると,確かにそうだと判るのですが(汗)そこを自分で判るように努力しないと.
>URL は消えて、Apple のみに
なりました.クリックは出来ませんが.--人狼 - 2002-12-19, 13:09:17
と,言うことでchocolate採用です.ただ…OS Xってクリッピングできないんですね(汗)でも,まぁ自分で後から読み直した時に判りやすい事も大切ですので,ちょっと過去に旅してきます.--人狼 - 2002-12-19, 13:10:28
>OS Xってクリッピングできない
が〜ん。--sumim - 2002-12-19, 13:27:22
ふたたび、TextURL にもどって、info と url: はゲッタ、セッタなのでいいとして、キモは actOnClickFor: のようですね( writeScanOn: はややこしいので今は無視しましょう)。ここでクリックしたときにどんなことをするのかを決めているようです。従って、この actOnClickFor: をオーバーライドするサブクラスを作れば、クリックしたときに別の何かをするハイパーリンクを作ることができることを意味します。そこで、実際に TextURL のサブクラスに TextClickTest を作って、クリックするとトランスクリプト(Transcript)に 'Hi! I'm Jinro...' と出力するハイパーリンクを作ってみることにします。--sumim - 2002-12-19, 13:34:54
トランスクリプトは Tools フラップの Transcript をドラッグ&ドロップすることでとりだせます。もちろんデスクトップメニューの open... → transcript でもということも念のため(^_^;)。トランスクリプトに何かを出力したいときは、Transcript(これは inspect-it すると分かりますが、クラスではなくグローバル変数で、TranscriptStrem のインスタンスが束縛されています。もっともクラスもグローバル変数に束縛されているオブジェクトに過ぎないので両者に本質的な違いはないのですが…) に show: という引数に文字列を添えたメッセージを送信します。改行は cr を送信します。従って、Transcript cr; show: 'Hello World!' を do-it すると、トランスクリプトをいったん改行して、改めて指定した文字列が追加されます。--sumim - 2002-12-19, 13:39:17
>実際にTextURLのサブクラスにTextClickTestを作って
作りました.久し振りだったので,ちょっと考えてしまいました>サブクラス.--人狼 - 2002-12-19, 13:45:04
TextClickText >> actOnClickFor: に、これと同種のコードを記述すれば準備完了です。actOnClickFor: anObject
Transcript cr; show: 'I''m Jinro!'.
^ true
I'm のシングルクオーテーションのエスケープを忘れないようにしてください。最後に true を返すのがお約束のようなのでそれに従っておきます。あとは、cmd-6 のコードをちょっといじって、TextURL の代わりに TextClickTest を作るようにすればオッケーです。具体的には、index = 7 ifTrue: [attribute _ TextURL new. の TextURL を TextClickTest に置き換えます。--sumim - 2002-12-19, 13:48:12
>クラスではなくグローバル変数
はい,inspect-itして確認しました.グローバル変数は結構あるのですね.
>いったん改行して、改めて指定した文字列が追加
これも確認出来ました.--人狼 - 2002-12-19, 13:48:26
これで cmd-6 の be a web URL link で作ったハイパーリンクは、トランスクリプトに I'm Jinro! と出力する機能を持つようになりました。インスタンス変数の url に束縛されている文字列を出力するように変更するのは簡単だと思います。試してみてください。--sumim - 2002-12-19, 13:51:18
>同種のコードを記述すれば準備完了
メソッドのオーバーライドは久し振りですね.準備完了しました.
>シングルクオーテーションのエスケープ
大丈夫でした.珍しい(汗)
>TextURLの代わりにTextClickTestを作る
やってみました.Transcriptにちゃんとクリックした分だけ表示されます.これはデバッグメッセージとして大変便利な使い方ですね.--人狼 - 2002-12-19, 13:55:44
>インスタンス変数のurlに束縛されている文字列を出力する
次のコードでできます.
actOnClickFor: anObject
Transcript cr; show: url.
^ true
--人狼 - 2002-12-19, 13:57:58
>グローバル変数は結構あるのですね
グローバル変数は Smalltalk というグローバル変数に束縛されている辞書の要素なので、Smalltalk size を print-it するとクラスを含めたグローバル変数の総数が、(Smalltalk select: [ :value | value isKindOf: Class ]) size とするとクラスの数が、Smalltalk select: [ :value | (value isKindOf: Class) not ] を inspect-it すると、クラス以外のグローバル変数の一覧を見ることができます。--sumim - 2002-12-19, 13:59:13
あとは、クリックしたときに同名のワークスペースがあればそれをアクティベートし、なければ作る…というコードをトランスクリプトへの出力の代わりに書けば当初の目的は果たせそうです。新しいワークスペースを開くのには、Workspace openLabel: 'title' でいけます。その前に、url に束縛されているのと同じタイトルを持つワークスペースを探さなければいけません。これには以前の SystemWindow class >> #windowsIn:satisfying: が使えそうですね。モデルが Workspace のタイトルが url で束縛されている文字列と同じウインドウを探せばよいわけです。見つかったら、それをアクティベート(activate を送信)します。どうしましょう。答えを書かずにとりあえず組んでみていただきましょうか? まだ無理っぽそうですか?--sumim - 2002-12-19, 14:08:35
>Smalltalk というグローバル変数に束縛されている辞書の要素
結構な数がありますね>辞書の要素.クラス以外のものは28ありました.notもメッセージなのだと再認識してました.--人狼 - 2002-12-19, 14:35:24
>答えを書かずにとりあえず組んでみていただきましょうか
とりあえず,やらせてくださいますか?ダメっぽかったらヘルプを願い出ます.明日で,この講義が始まってからちょうど一ヶ月.そろそろ自分で一つくらい何とかしてみたいもんです.--人狼 - 2002-12-19, 14:36:22
>notもメッセージなのだと再認識
よい傾向ですね。--sumim - 2002-12-19, 14:51:35
>とりあえず,やらせてください
了解です。がんがってみてください。藁--sumim - 2002-12-19, 14:52:27
>がんがってみてください
ありがとうございます.やってみました.
actOnClickFor: anObject
|winClct|
winClct _ (SystemWindow windowsIn: ActiveWorld satisfying: [ :win | (win externalName) = url]).
(winClct size = 0) ifTrue: [Workspace openLabel:url] ifFalse: [(winClct first) activate].
^ true
としてみました.--人狼 - 2002-12-19, 15:16:56
すばらしいですね。あとは SystemWindow のモデルが Workspace だという制限を加えておいたほうがよいと思います。で、こんなかんじでどうでしょう。actOnClickFor: anObject
| winCollection |
winCollection _ SystemWindow
windowsIn: ActiveWorld
satisfying: [ :win |
(win model isKindOf: Workspace)
and: [ win externalName = url ]].
winCollection isEmpty
ifTrue: [ Workspace openLabel: url ]
ifFalse: [ winCollection first activate ].
^ true
括弧をちょっと減らして変数名をきもち省略しなくしてみました。自分は省略しまくりなのに他人のだと気になる…(^_^;)。--sumim - 2002-12-19, 16:12:34
and: の引数がブロックであることに注意してください。and: はレシーバが false の場合はそこで断念して引数の評価はあらためてしないので、レシーバが true でないときには正常に動作しない記述をブロック内にするときに重宝します。我々がよく知る論理積としては、別に & というのが二項メッセージとして用意されています。or: と | の関係も同様です。念のため。--sumim - 2002-12-19, 16:17:08
>SystemWindowのモデルがWorkspaceだという制限
おっしゃる通りですね.その制限は必要ですね.
大変読みやすくなりました.有り難うございます.
変数名は,えてして「自分が判りやすい」と言う感じでつけてしまいますので,他人の命名は気になりますよ〜.--人狼 - 2002-12-19, 16:20:24
苦労話などよかったらきかせてください。--sumim - 2002-12-19, 16:20:39
>他人の命名は気になります
私だったらたぶん wins にすると思います。--sumim - 2002-12-19, 16:22:12
>and: はレシーバが false の場合はそこで断念して引数の評価はあらためてしない
なるほど.ブロック内にそのような制限がある場合には重宝しますね.&は普通の論理積ですね.
isEmptyに気付かなかったんですね>自分(汗)--人狼 - 2002-12-19, 16:22:56
>苦労話などよかったらきかせてください
苦労話と言うか笑い話なのですが(汗)変数名に限らず「命名」する時には自分が判りやすいと言う基準でつけがちです.それを製品から排除するために「命名規則」等と言うものがしばしば作られます.そこには「整数型ならnから始まる」とか,「命名はハンガリアンルールで」とか「省略記法の例」とか,ことこまかに規定がありまして…覚えられません.結果として時間に余裕のある内は規則を見ながらコーディングする為に時間だけかかって…当然時間が足りなくなってくると,規則なんぞ見ている暇がなくなり独りよがりの命名になって…結果として一つのソースの中に複数の命名基準が存在する…と.--人狼 - 2002-12-19, 16:27:11
>私だったらたぶんwinsにする
なるほど.私が先に書いたのは「これはコレクションでっせ」と言う事を,そこはかとなく伝える&自分に言い聞かせるためでした.他にもリストやら配列やらと,複数要素を格納する手段はあるので,「ここはコレクションです」と言う気持をこめて(誰に?)--人狼 - 2002-12-19, 16:29:20
お仕事だといろいろと大変ですね。>命名規則っぽいもの さて、あとは UI を整えて完成させましょう。ただ、クラス名がちょっと…ですね。これを修正したいのですが、いろいろと問題が起こるのでこれもいっしょに見ておきましょう。まずクラス名の変更ですが、ブラウザのクラスリストペインで、rename class... を選びます。そこで TextWikiName などとそれっぽい名前にして accept します。すると、元の TextClickTest を使っているメソッドでエラーが起こるので…とやりたかったのですが、クラス名の変更の場合は参照しているメソッドを列挙してくれるみたいなのでこれらも直して起きましょう(^_^;)。インスタンス変数だったかは列挙してくれないので、変える前に参照するメソッドを列挙しておいて、変えてから直す必要がありそうです。いずれにせよ、名前の変更をすると相互参照の見地から変なことが起こるのであまりしないほうが無難です。--sumim - 2002-12-19, 16:46:37
>お仕事だといろいろと大変
そうですね(苦笑)複数のメーカーが絡むともうわけわからんです.
>名前の変更をすると相互参照の見地から変なことが起こる
了解しました.クラス名を考えるときはよく考えてからにします.面倒な事になりそうですし.--人狼 - 2002-12-19, 16:51:28
さて、UI ですが、TextURL を殺してなお cmd-6 を間借りしたままってのも寂しいので、TextURL は元に戻して、改めて cmd-マイナスと重複している cmd-9 に割り振ることにしましょう。ちょうど、ParagraphEditor >> #changeEmphasis: が開いた状態だと思うので、ここで、 (keyCode between: 7 and: 11) ifTrue:
[sensor leftShiftDown
ifTrue:
[keyCode = 10 ifTrue: [attribute _ TextKern kern: -1].
keyCode = 11 ifTrue: [attribute _ TextKern kern: 1]]
ifFalse:
[attribute _ TextEmphasis perform:
(#(bold italic narrow underlined struckOut) at: keyCode - 6).
oldAttributes do:
[:att | (att dominates: attribute) ifTrue: [attribute turnOff]]]].
とあるところを (keyCode between: 7 and: 11) ifTrue:
[sensor leftShiftDown
ifTrue:
[keyCode = 10 ifTrue: [attribute _ TextKern kern: -1].
keyCode = 11 ifTrue: [attribute _ TextKern kern: 1]]
ifFalse:
[keyCode = 9
ifTrue: [attribute _ TextWikiName new.
(thisSel _ attribute analyze: self selection asString)
ifNil: [^ true]]
ifFalse: [attribute _ TextEmphasis perform:
(#(bold italic narrow underlined struckOut) at: keyCode - 6).
oldAttributes do:
[:att | (att dominates: attribute) ifTrue: [attribute turnOff]]]]].
とでもしましょうか。ちょっとばっちいコードですが、もともとがそうとう汚いのできっと許してくれるでしょう<誰が?(^_^;)。--sumim - 2002-12-19, 17:06:41
>TextURLは元に戻して、改めてcmd-マイナスと重複しているcmd-9に割り振る
やってみました.大丈夫です.ifNil: [^ true]]は選択されている場所が無かったら,と言う事ですか?
>きっと許してくれるでしょう
誰も咎めませんって(汗)--人狼 - 2002-12-19, 17:19:59
ええ。でも Google にキャッシュされ始めて、今や誰が見ているか分からないですからね(笑)。気を付けないと(^_^;)。さて、このように UI の拡張や変更も簡単にできまっせ、というお話をしたわけですが、最後にひとつ。せっかく作ったのでこれを公開すんべ、というときにどうしたらよいかという話です。ま、すでにお話ししたチェンジセットを使うわけでなんのひねりもないのですが…(^_^;)。まず、チェンジセット(simple change sorter)を開きます。ここで、クラスリストペインには、ParagraphEditor と TextWikiName が、またそれぞれには changeEmphasis: と actOnClickFor: があるはずです。それ以外のクラスやメソッドがある場合は、何かのテストをしたときに remove form changes しそこねたものなので、ここで選択して delete class from change set などとしておきましょう。最後にチェンジセットの名前を適当なものに変えて、黄ボタンメニューから file out を選びます。--sumim - 2002-12-19, 17:34:38
>Googleにキャッシュされ始めて、今や誰が見ているか分からない
それは私も気を付けないと(汗)
>せっかく作ったのでこれを公開
なんて書くとぐぐった人たちが来ちゃいますよ(笑)
>チェンジセットの名前を適当なものに変えて、黄ボタンメニューか file out
ここでリネームしている理由が判りません.すみません.チェンジセットの名前とプロジェクトの名前って対応してましたよね…--人狼 - 2002-12-19, 17:43:40
ただ、ここで吐きだされる .cs ファイルを見てみると分かるのですが、クラス名の変更も含まれています。これは、名前の変更以前に .cs があって、それを用いた仮想イメージでこのチェンジセットを適用したときに正常に動作するようにするための配慮です。このチェンジセットははじめてのリリースなのでこの部分は必要ありませんので削除してしまいましょう。チェンジセットから削除するときは、チェンジセットリストペインのシフト黄ボタンメニューから trim history を選びます。改めて file-out すると当該記述が消えていることが確認できると思います。--sumim - 2002-12-19, 17:46:08
>クラス名の変更も含まれて
あら,ほんとですね.そう言う配慮があるんですね.ご教示頂いた通りの操作で当該記述は消えました.file-outすると,ファイル名に自動で番号が付与されるのですね.--人狼 - 2002-12-19, 17:54:39
>ファイル名に自動で番号が付与される
ええ。これは簡単なバージョン管理に使えます。--sumim - 2002-12-19, 18:13:02
>ここでリネームしている理由
深い意味はありません。プロジェクト名として付けた名前が必ずしもチェンジセット名として相応しくない場合もあるので名前の確認の習慣を付けておくほうがいいかなぁと。--sumim - 2002-12-19, 18:14:25
あと、こうした既存のクラスのメソッドに変更を加える方法での拡張は、システムのバージョンアップ時に簡単に上書きされて、いっさいなかったことになるので、公開するにしても自分で気に入って使うにしても、アップデートストリームには注意を払っておく必要があります。自分で使うときにはアップデートをしない、公開に際しては動くバージョンを限定してしまうという手もありますね。--sumim - 2002-12-19, 18:18:04
>簡単なバージョン管理
そうですね,そう言う用途にも使えますね.--人狼 - 2002-12-19, 19:15:04
>名前の確認の習慣
了解です.何か深い意図があるのかなぁ,と考えてしまいました.(実はトラップを恐れている?(苦笑))--人狼 - 2002-12-19, 19:16:09
>アップデートストリームには注意
そうですね,既存のクラスのメソッドに変更を加える等と言うのは,そこら辺のOSでは考えられない事なので,ここは十分に注意が必要ですね.
>公開に際しては動くバージョンを限定
そう言う手法もあるのですね.versionでcmd-Eしてみましたが,予想通り数が多くて撃沈です.--人狼 - 2002-12-19, 19:19:26
このページを編集 (64968 bytes)
|
以下の 1 ページから参照されています。 |
This page has been visited 2793 times.