Path: sran265!katsu From: katsu@sra.co.jp (WATANABE Katsuhiro) Message-ID: Date: 21 Dec 93 17:21:45 Organization: Software Research Associates, Inc.,Japan In-reply-to: rsekido@hisgw.hitachi-his.co.jp's message of 15 Dec 93 07:33:22 GMT Newsgroups: fj.lang.st80 Subject: Re: dynamic class definition (In Japanese/Kanji) Distribution: fj References: <131@hisgw.hitachi-his.co.jp> 記事 <131@hisgw.hitachi-his.co.jp> で rsekido@hisgw.hitachi-his.co.jp (SEKIDO Ryoichi) さんいはく > ST80 でダイナミックにクラスを定義することはできるんでしょうか.  できます。実は、クラスがダイナミックに作られるのは Smalltalk ではごく 普通のことです。ブラウザーで対話的にクラスを作るのも、ライブラリを file in してクラスを読み込むのも、全て smalltalk インタプリタ自身が(動的に) やっていることを思い出してください。  PPS の ObjectWorks R4.1 を例にとりましょう。クラスを作るには スーパークラス subclass: #作りたいクラス名シンボル instanceVariableNames: 'インスタンス変数群をスペースで区切ったもの' classVariableNames: 'クラス変数群をスペースで区切ったもの' poolDictionaries: 'プール変数用辞書群をスペースで区切ったもの' category: 'クラスが属するカテゴリ名' のようなメッセージを送ります。これには見覚えありますよね。ブラウザで 何かカテゴリを選んだとき、クラス作成のテンプレートとしてコード用の窓に 出てきたり、クラスの definition を見るときに出てくる奴です。(つまり クラスを作成するときには、普通はテンプレートを埋めた後で "accept" しますが、実は "do it" でもかまわなかったのでした。)  クラス DynClass の中にメソッドを定義する(あるいは入れ替える)には、 DynClass compile: 'ソースコードを表現する a String もしくは a Text' classified: #プロトコル名シンボル のようにします。  逆に、クラス(とそのサブクラス群)の削除は removeFromSystem、メソッ ドの削除は removeSelector: を使えばよいでしょう。  上以外にも error notification とか、change logging などに関して、 色々な変種があったと思います。Behavior,ClassDescription,Browser 等の クラスの実装を覗いてみると面白いと思います。  クラスの構造定義もメソッドもあらかじめほぼ決まっていて、沢山の メソッドを定義しなければならないという状況なら、a Stream(a String として メソッド中に埋め込んでおき、使うときに aStream を生成する)にコードを file in 形式で保存しておいて、動的に fileIn メッセージを送るというのが 簡単だと思います。  これは、ファイル上に置いてあるコードを動的に file in する方法と比べて、 単にコードがイメージ上に移ってきただけで、本質的は違いません。記憶領域を 無駄使いしているともいえます。しかし、ファイルの存在の保証やファイル名の 指定(すなわち外部環境とのやり取り)など、細かい点に注意をせずとも 頑強性が達成できるというメリットがあります。 > アプリケーションの中でユーザが好みのクラスを定義したい, > という場合に必要になると思うのですが.  Compiler class>>evaluate:, evaluate:for:logged: などのように a String を Smalltalk の式と見て eval ってくれる仕組みで解決できる場合もあるのでは。 -- 渡邊克宏@SRA