top recent

Delphi


目次

  1. DelphiのMethodPointer...
  2. 質問:Delphiのコードって...
  3. Delphi(Object Pascal)で書いたIteratorのサンプル...
  4. DeCAL...
  5. Delphree...
  6. Form単位での永続化...
  7. SDL...

DelphiのMethodPointer

自由変数を持つ関数 (プログラミング言語) と、似ているような似ていないような…

ただ、自由変数を持つ関数 (プログラミング言語)の代用品として使うことは技術的に可能、かも知れない。

DelphiのEventProcedureとかで使われているMethodPointerという型/変数/値は、
Method自体のアドレスと、そのMethodを持つ任意(プログラマ恣意)のObjectの参照と、
が入っている、メンバ数2個のレコードである。
ほら、似てるでしょ?

signature: 戯

----
クラスのメンバ関数へのコールバック

こういう文脈でこういう意味でクラスという単語を使うのは痛い(=C++洗脳による弊害だ!)とか、
「C++でコールバック関数に出来るのはクラスのスタティック関数だけだ」というのは実は嘘だ
(でも悪路バティックなのでヤリたい気分にはならない:てーかやり方忘れた(ぉ))とか、
微妙な部分はあります(まぁご本人の責任じゃないと思うけどね。C++が悪いのさ)が、
それはさておき、この、

>TMethod = function: string of object;

という型定義に注目。
強い型な言語なんでいちいち型を作らんとならんのが面倒ではあるが、
#まぁ頻出するものは標準ライブラリで定義済みだが。
それを差し引いても、こういうのが出来ると出来ないとでは大違いです。

ちなみに型をいったん作ればRTTIで動的に参照することも当然可能。
DelphiのIDEはその情報を元にして、イベントプロシジャの代入互換性の評価
(とプロシジャのソースの自動生成)を行っている。

余談:
言語のコンパイル結果として作られるClassとかの型定義を、どうやってIDEが参照するか、というと、
コンパイル結果をDLLに(も)しておくことで実現してる。
IDEが直接関知しなきゃならないTComponent系のClassを作ると(正確には、そのClassをRegister手続きに渡す(だったかな)と)、
その結果を通常のオブジェクトファイルだけじゃなくDLLにも反映し、IDEはそのDLLを「リロード」する。

余談^2:
リロード周りではトラブルが時折起きる。OSのほうのトラブルが(笑)。
特にKylixは、その開発(だよね)過程で、Linuxの動的ロードの問題点を発見指摘する羽目になっちゃったらしい(^^;

余談^2.5:
開発手順上の手抜きとして、このDLLのリロードを「やらない」というのが、かつて有った(今もか?)。
Componentを開発してるときにDLLのリロードをやりまくるのはウザイ(し、バグがあったら簡単に
IDEごとクラッシュしちゃう。なんせNativeだから…)んで、
IDEが認識してるComponent(DLL)が若干「古い」のを覚悟の上で、直接生成するExeのほうオブジェクトファイル
だけをコンパイル/更新するという手順でやる。もちろん数時間格闘して安定したらDLLを作り直すべきだし、
IDEから直接見えるInterface(Property定義とか)に変更が有ったときはDLLの版を合わせないと
悲劇(永続データのversionが不整合するんで)になるが。

[[id:575]] 2002-07-30 15:45:58


質問:Delphiのコードって

IDEで生成したあとエディタとコンパイラだけでメンテできたりするんでしょうか

----
IDEが生成する(もちろんユーザーの手も借りるが)ものは、
「ソース」と「Form定義ファイル」です。

前者は問題なくいじれます。VC++みたいに(ぷ)少々いじったくらいで
IDE管理と不整合起こして死亡なんてことはないです。
きちんとParseしてるんだと思います。マクロやコメントに頼っていない。

後者はTextモードで出力すれば可読テキストになります。
厳密に文法がどうなってるかはよく覚えていません(ぉ)が、
どうにかなるレベルだと思います。

Form(GUI画面)定義に基づく情報が、「ソース」に(ほとんど)反映"されない"のが
Delphiの(多分他の多くのIDEと比べての)特徴です。
そういう情報はあくまで永続化データとして扱います。それが後者のファイルに落ちます。

「ほとんど」という曖昧(^^;な言い方になるのは、たとえば
Form上にComponentを貼ると、FormからCompoを参照する(デフォルトの)メンバ変数が1つ用意される
(剥がすとその変数は無くなる)のですが、その変数の生成削除は自動的に行われます。
例外はこれくらいかな。ほかの情報はFormファイルのほうに行きます。
-Compoのconstructorを呼び出したりCompoにconstructor引数やpropertyを色々与えたり、という部分は一切ソース化されません。永続化とRefrectionを駆使するライブラリが背後で全部始末してくれます。
--constructor呼び出しすらソースに書かなくて済む(=ライブラリにとって「未知の」classのInstanceを作れる)のも、MetaClassとかのお陰です。
--これに慣れるとむしろVCやJBuilderの後進(ぉ)性を見たときビビります。なんでソースが干渉(^^;される必要が有るの?と。
---DelphiがRAD「のために」作られた(強型付けの)言語だ、と呼ばれる所以です。もちろん他の多くの場面ででも役立ちますが。
---Javaなら自分アプリの.jarの中に永続データを仕舞えるはずですが、もしかしてあんまり活用されていない??
--初期化の内容がソースで「実行」されず、定義ファイルでいわば宣言的に行われるので、無から初期状態に至るまでの道のりが「文脈」に振り回されないというのはメリットだと思います。
---(日経だったと思うが)雑誌に「(バグを減らすためには)初期化はPropertyじゃなくソースで行うべき」と書いてあったが、大嘘だと思う。文脈に振り回されるソース上での記述のほうが危なっかしかろう。
---初期化と実行という概念の定義を故意に捻じ曲げる(ぉ)ことでこの問題を克服した「つもり」になってるC++は、困った言語だと思う。Constructorは実行に非ず、という解釈は方便に過ぎないようにしか見えない。
----C++においてConstructorを何らかのLibraryやFrameworkに囲い込むことが困難なのは、C++のMeta機能が貧弱なせい。

----
ただ、GUI(とイベントモデル)に関係ないプログラムの部分はともかくですが、
GUIそのものに強く関わる部分は、GUIなWidget配置エディタ(テキストエディタではない)無しに取り組むなんて「無茶」だと思います。
つまりIDE無しという前提自体が変だと。

逆に言えば、レイアウトマネージャに半分任せてテキストエディタだけで組もうとする努力のほうこそ、
そんなのどこまで価値があるんだろうか?と疑問に思ってしまう。

つまり、Widgetエディタもテキストエディタも「エディタ」という同列の存在だよね?ということです。
----
同意です。しかし逆もまた真なり。
初めてDelphiの入門書か何かを読んだ時、サンプルのラーメンタイマーか何かのアプリを作りましょう、という章でメニューとかタイマーとか、GUI部品でないものをどこでもいいから貼り付けて下さい、という説明を読んだときに非常に面食らったのを覚えています。

そんなのわざわざ妙なアイコンにして、なんでフォームに貼り付けなくちゃならないんだと。
フォームといわれているのは実は入れ物のフタで、それをカパッと開けて下さい、中に歯車回ってるでしょう、その中に一緒に放り込んで下さい、くらいの芸はないんかと。

きっと2-wayだと層が一つ足りないんだよね。

----
なるほど。Delphi用語でいう非ビジュアルComponentの問題ですね。鋭い(=痛い)指摘かも。
-Form(初代から伝統の)が、何でも載せられるコンテナとビジュアルなコンテナを、兼任してるんですね。
--これはメリットでもありデメリットでもあります。
--というのも、Delphi使ってるとむしろ、MVCすれば偉いってものなのか?という疑問を抱くようになっちゃうんです(俺は)。
--Viewを分離すればそれでいいのか?というか、分離の主軸はView vs Modelであるべきなのか?というか。
--DelphiはMVCとは違う切り口でモノを仕分けるような方向で進化(本質は初代から変わってないが)したように思います。
---たとえば。DelphiのIDEには、プロパティエディタで、あるCompoのPropertyに代入するための(同じForm上の)他のCompoの参照を(by nameで)一発取得する機能が有りますが、あーゆーもの(操作性)との相性は、ビジュアルか否かでCompoを分類する考え方と、馴染まないように思います。
---つまり「このWidgetに」関連するモノは「このWidgetのそばに」置くのが、直感にも合理にも適うだろう、という考え方なんだと思います。
---デザインと性能は「二律背反」ではない――morph3開発者インタビューのように、MVCを分離するのではなく、MVCをまとめた小さい単位を組み合わせる、という考え方も、アリだと思うのです。

-妥協(?)案。現在(ver2以降)のDelphiでは、非ビジュアルなCompoだけを貼れる「DataModule」が導入されました。正調MVC(?)をしたい時はこちらをどうぞ。

-Formの欠点として、Form自体が入れ子になる(Form自体がWidgetになる)ことが不可能、という点があります。
--ver5以降、その代案として、WidgetとしてFormなどに貼れるFormもどき「Frame」が用意されました。でも遅すぎる登場だし、FormやDataModuleと互換クラスでもないんで、半端っす。
---クラス階層を決めるとき、Windowsの枠組みに拘りすぎた面があるかと。MFCよりは遥かに良いとはいえ…
----ちなみにWindowsはそういう意味では出鱈目ですね。Windowを直感に反して"Eventの受信者"と定義(?)しちゃったので、表示と無縁なTimerEventの処理にすらWindowが必要になる…
-本来ならFormとDataModuleを親子入れ子関係にする(Formの中にDataModuleを入れ、そのDMが「歯車」領域を担う)のが良いんでしょうけど、それはサポートされていません。
--ただ、上でも書いたように、歯車は隠せという考え方でなくても良い、とも思えるんですよ…

-まあDelphiは、真の意味でのVisualProgramming(GUI「で」作るRAD)と単なるGUIを作るRADとを、混同したモデルだとも言えますね(^^;

[[id:864]] 2002-07-30 15:46:34


Delphi(Object Pascal)で書いたIteratorのサンプル

http://www.hyuki.com/dp/
http://www.freeml.com/message/patterns/1414

[[id:1063]] 2002-08-28 15:50:48


DeCAL

http://sourceforge.net/projects/decal/
コンテナ、アルゴリズム、ジェネリック、などのキーワード。
C++のSTLみたいな方向性?
FPな方角へも向いている?

----
これの説明書の和訳は存在するのかな?
-無いならやろかな?
-でもやっても公開できるんだろうか?自分用だけにやるのも間抜けだし…
--本家らしき会社の頁は死滅してるし…
--上記SF頁に赴けばいい?

----
-親戚:JGL (Java)
-Delphiの各種の型(IntegerとかObjectとか)を統一的に保持する手段として、Delphiに元々(何故か(^^;)用意されてる、array of constと呼ばれる構文を使うらしい。これを使うと、Pascal子孫のくせに、型がばらばらな要素からなる配列を作れるので。
-なに?GCが有るのか?Boehm Collectorという言葉が。
--素晴らしい!GCも無いしC++ライクな静的寿命管理も無いDelphiではこーゆーProgrammingは正直辛いのだが、GCを後付けしたなら話は別。
---漏れも久々にDelphi Programmingに戻ろうかなあ…:-D~~~
-Closure やはりDelphiのTMethodの仕掛けを使うらしい。
--Morphing Closure Pascalの関数/手続きをTMethodでラップする仕掛けらしい。
---漏れも久々にDelphi Programmingに戻ろうかなあ…:-D~~~
--C#を非GUIソフト作りに使うのは、(Delegatesの仕掛けが)無駄なだけだ、と言っていた人が居たが、そうでもなさそうだ。こういう活路が有るのでは?

[[id:1064]] 2002-08-31 10:36:51


Delphree

http://delphree.clexpert.com/ Welcome to the world of Delphi Open Source Development

[[id:1079]] 2002-08-30 15:26:05


Form単位での永続化

DelphiにもSqueakに対するストレス (Smalltalk)みたいなストレスはあるか?ということを考えるとき、
ズルい(良い意味でも悪い意味でも)回避策としてのFormという仕掛けのことを忘れるわけにいかない。

Form…Delphiのクラス名でいうTForm…は、所謂Windowに対応する。

で、ズルいのは、永続化の単位がFormである、という点。

ミクロ面では、Component個々が自分の情報を記録する機能を持っているが、
マクロ面、つまり例えばDelphi IDEが普段情報を永続化する大きいほうの単位は、Formクラスである。

IDEでFormを1つ作成すると、それに一対一で対応したTFormクラスの子クラスが1つ作成される。
この1クラスあたり1つのForm永続化ファイルが作成されるわけである。

で、そのファイルの「中」で、Componentの名(Nameプロパティ)の一意性が、保証されるようになっている。
そして、その名に基づいて、参照を永続化したり復元したりするのである。

-Form「クラス」についての永続化なので、厳密にいえば普通のInstanceの永続化管理とは違う。
--同じFormクラスのInstance(つまり同じWindow)を複数作ると、同一の永続ファイルを参照することになる。
--もっとも、IDEによって生成される永続情報は、コンパイル後のアプリからは(特にソレ系のプログラムをしない限り)ReadOnlyなので、これで一応破綻しない。
--ここらへんがズルイ。シリアスな永続化問題(Instanceの一意性とか)を巧みに回避していることになる。
-プログラム(Project:(しばしば複数の)Formクラスの集合)全体での一意性は、原則として問われない。
--他のFormの情報を参照する仕組みも、今の版のDelphiにはある。Formの複数Instanceを作ってしまうとアレな事になるが…
-名前は、自動生成されるに任せる(クラス名+クラスごとの連番)のもよし、自分の意志で変更するもよし。
--(InspectorでNameプロパティを)変更すると、同時に、FormクラスにおいてそのComponentのデフォルト(1つ目)参照を持っているメンバ変数の名前の宣言も、変化する。
---自動追随するのはFormクラスの宣言の部分だけ。メソッド実装の中までは関知しないので、リファクタリングを期待できるわけではないが、
----変更すれば大抵コンパイルが通らなくなる(エラー個所をIDEが教えてくれる)ので、修正してまわればいい
----コンパイルは超絶速い(^^;
----…ので、まあなんとかなるもんである。
--名前を変更するのは、プログラム上からもやれる。
---もちろん普通のプログラムでは、Nameプロパティをいじっただけでソースが変化するはずもないが、Form自身のソースを生成することが期待されるプログラミングをする(!)とき、Componentの名をスムーズに決定できる。

----

[[id:1080]] 2002-08-30 16:05:09


SDL

----
1:imple Directmedia Layer
http://www.grulic.org.ar/~dmoisset/sdl4fp/english.html FreePacal用

----
2: DeCAL (#4)の旧称(^^;。
StandardDelphiLibraryだそうだ。(でもStandardってのはナシだべや)

[[id:1087]] 2002-08-31 18:34:44


top recent

HashedWiki version 3 beta
SHIMADA Keiki