[#29469] エラーを捕まえたいのですが ... — Sakae Kobayashi <sakae@...>
困った時に出てくる、小林榮です。
まつもと ゆきひろです
In message <988708753.422219.10637.nullmailer@ev.netlab.zetabits.com>
[#29471] rd2man について — "NAITOH Jun" <naitoh@...>
こんにちは、内藤と申します。
[#29480] xpstore — akira yamada / やまだあきら <akira@...>
[#29490] Re: [ruby-talk:14555] Ruby as a Mac OS/X scripting language — maili31s@... (SugHimsi == SUGIHARA Hiroshi)
すぎむし速報。↓だそうです。
古暮でございます。MacOS X をいじり始めて一週間程度なのですが,
始めて投稿します。福田と申します。メインにはMacを使っていますので、Rubyを直
古暮でございます。
こんにちは、近藤と申します。
古暮でございます。
[#29504] クラスブラウザ with ReFe — kadu <kadu3@...16.alpha-net.ne.jp>
こんにちは。kadu です。
[#29513] drb-1.3.2 — Masatoshi SEKI <m_seki@...>
[#29521] A problem with the latest irb — "Akinori MUSHA" <knu@...>
IRB 最新版(0.7.3)ですが、どういうわけか、定義したメソッドを
[#29524] tr range? — kiri@...
桐山です。
新井です。
桐山です。
新井です。
[#29544] enriching standard extention libraries: syslog, zlib, etc. — "Akinori MUSHA" <knu@...>
Syslog モジュールを標準添付にするというのはどうでしょうか。
[#29547] strftime.c でのエラー — "Kazuaki Miyauchi" <miyauchk@...>
宮内といいます。
[#29550] UDP でバイナリデータを送りたいのですが? — "Kenji Takahashi" <kenji4553@...>
はじめまして。
[#29587] duplicate fragment identifiers in ruby-refm.html — Tanaka Akira <akr@...17n.org>
ふと気がついたのですが、
[#29597] media watch 2001.05.08 — Noritsugu Nakamura <nnakamur@...>
[#29603] Importing shell.rb — "Akinori MUSHA" <knu@...>
At Mon, 7 May 2001 14:50:32 +0900,
[#29604] Importing eachdelegator.rb — "Akinori MUSHA" <knu@...>
少し前に登場した、岡田さん作の EachDelegator:
まつもと ゆきひろです
At Wed, 9 May 2001 17:58:34 +0900,
原です。
[#29644] rwiki.rb でエラー — norio goto <goto@...>
お世話になります、後藤@横河工事です。
後藤@横河工事です。
後藤@横河工事です。
In <20010514192948A.goto@yokogawa-kouji.co.jp>
後藤@横河工事です。
後藤@横河工事です。
後藤@横河工事です。
[#29647] String#index — OHARA Shigeki <os@...>
大原です。
[#29665] frozen string in a |= b — kiri@...
桐山です。
[#29675] with(obj){ } が欲しい。 — Take_tk <ggb03124@...>
例によって、ワタシ好みののりクエストですみません。
さくです。
Take_tkさんの<20010515205133.DFBA.GGB03124@nifty.ne.jp>から
たけ(tk)です。
まつもと ゆきひろです
たけ(tk)です。
まつもと ゆきひろです
たけ(tk)です。
[#29707] OBJECT DAY2001 — "K.Kosako" <kosako@...>
OBJECT DAY2001から帰ってきました。
まつもと ゆきひろです
渡辺哲也です。
YARPC関連で動いてお騒がせしている(_o_)高橋征義です。
あおきです。
なひです。
なひです。
いがらしです。
なひです。
あおきです。
[#29720] rand(1<<32) — TAKEUCHI Hideki <take@...>
竹内です。
[#29721] Cygwin で Ruby をコンパイルするとエラーがでます。 — "Inoue" <inoue@...>
はじめまして、最近Rubyをはじめました井上と申します。
[#29759] WinNT Ruby CGI KILL? — "Inoue" <inoue@...>
井上です。
[#29766] インストールができません。 — Jun-ichi Murakoshi <murakosi@...>
長沢@新大OB です。
[#29788] marshaled time format differ — IWATSUKI Hiroyuki <don@...>
岩月と申します。
まつもと ゆきひろです
岩月と申します。
岩月と申します。
From: IWATSUKI Hiroyuki <don@na.rim.or.jp>
岩月と申します。
岩月と申します。
At Tue, 29 May 2001 00:23:31 +0900,
岩月と申します。
At Tue, 29 May 2001 09:10:26 +0900,
[#29812] A request to RAA (was Re: YARPC 19101) — Takahiro Kambe <taca@...>
In message <20010527174810.632346.eban@os.rim.or.jp>
[#29824] Windows 版 Ruby — "U.Nakamura" <usa@...>
こんにちは、なかむら(う)です。
[#29853] "" で行われる展開を eval 無しで… — ABE Shigeru <shiger-a@...>
みなさま、はじめまして。阿部といいます。
From: ABE Shigeru <shiger-a@nifty.com>
阿部です。
From: ABE Shigeru <shiger-a@nifty.com>
こんにちは、阿部です。
[#29864] ActiveScriptRuby について質問です — たくみ <taku3@...>
原 忠司と申します。
[#29880] autoconf.rb — nobu.nakada@...
なかだです。
[#29886] mod_ruby and eruby — norio goto <goto@...>
後藤@横河工事です。
始めまして,田代と申します.
前田です。
In message <87hey3pg1w.wl@studly.priv.netlab.zetabits.co.jp>
[#29911] w3m のコンパイルエラーが起きました — "Inoue" <inoue@...>
井上です。
[#29941] Ruby ライセンスについて — matz@... (Yukihiro Matsumoto)
まつもと ゆきひろです
In message <991297854.779223.23013.nullmailer@ev.netlab.zetabits.com>
At Thu, 31 May 2001 18:00:18 +0900,
有馬@横浜、忙しいはず..です。
[ruby-list:29517] Re: [ruby-talk:14537] Rajah: Ruby-Java integration
すぎむし。
ウワサの Rajah プロジェクト紹介文書の和訳です。
よろしければご活用ください。
こなれない部分や強い意訳が目立ちますがあしからず。
--
SugHimsi == SUGIHARA Hiroshi
maili31s@clio.ne.jp
On Wed, 2 May 2001 16:11, DM & MS wrote:
こんにちは。ダン(Dan Munk) ならびに マシュー(Matthew Spencer) と申します。
ここのところの Ruby/Java 統合に関する議論のスレッドに注目していました。
その一方で、ひそかにものを調べたり開発をしたりしていましたが、
そろそろ時期が来たかと思い、このプロジェクトを発表します。
「Rajah」という名前でお披露目いたします。
Ruby 言語と Java 言語をブリッジします。
下記の開発のあらましにあるように、これは現時点までの内容です。
ほんとにあらましだけなのはご容赦ください。
開発者方面にはこまかくご紹介したいところなのですが、Ruby コミュニティに
仕事の進行状況をこの文書でもって具申する意味もありますので、あしからず。
Rajah そのものの話にかかる前に、言っておかねばなりません。
この文そして Rajah そのものに関して、お知恵や意見は、どんなものにでも
大変関心があります。このプロジェクトの未来について、われわれの心は
開いておりますので、どんな入力でも取り入れたいのです。どちらかといえば、
Ruby の方は新米に近いでしょう。だから、Rajah がただ単に機能的に充分な
拡張となるかどうかにとどまらず、Ruby/Java ソリューションとして「完璧な」
ものに仕立てられるかどうかが、たいへんに気がかりなところなのです。
ご意見お便り、お待ちしています!
Dan Munk
danmunk@hotmail.com
Matthew Spencer
matthewdspencer@yahoo.com
============================================================================
1. まえがき
2. 道案内
3. 設計
4. 横田わる問題
1. まえがき
----------------------------------------------------------------------------
「Rajah」は、Ruby 言語と Java 言語のブリッジを提供する、オープンソースの
プロジェクトです。Rajah プロジェクトでは、3つの「一里塚」を立てようと
しています:
+ まずは Ruby から Java へ。
この仕事の主要な部分には片がつきましたが、なにせ Ruby の方は
不慣れなので、これで正しくいっているかどうかが心配です。
(そういうわけでこの投書とあいなりました ^^;)
Java で書かれた Ruby 拡張が、一里塚への仕上げの旅となるでしょう。
これにはまだ手をつけていませんが、今ある C による拡張の構成を
できるだけマネしてゆこうと思っています。
+ JVM から Ruby へ。これが第2の一里塚です。一般的なアプローチと
構成は考えてきましたが、実際に実装するには至っていません。
+ 第3の一里塚は、Ruby インタプリタの pure Java による実装です。
この文書の残りでは、第1の一里塚、「Ruby から Java へ」の詳細設計と
実装に焦点を当てます。文書のどの部分に関する反応も、またアイディアも、
たいへんありがたく受け取らせていただきます。
2. 道案内
----------------------------------------------------------------------------
反応をいただいて(ほしいなぁ)加えるべき変更を実装したらば、RAA に
αビルドを 5/14 に登録するリリース計画を立てています。
変更の深さ大きさ次第では、一・二週間ずれることもありうるでしょう。
この際には、継続的なバージョン管理やスナップショット提供のために
Sourceforge の CVS を使うことになるでしょう。
極端流プログラミング(XP)隊の一員二員ですから(RubyUnitのご努力に感謝)、
水面下では、各一里塚に対して、何度も反復練習を積み重ねてきました。
第1一里塚までの反復練習は、皆さんからいただいたものによる作業を含め
られるようになったところで更新して、Sourceforge に掲載する見込みです。
向こう側に続く一里塚の方へは、その手前の一里塚にたどり着いて、
そちらがそれなりの品質になるまでは、出発いたしません。
当方がテストできる環境は、Solaris(Sparc 7, 8)、Linux 何種類か、それと
Windows 98/NT/2000 です。これ以外のプラットフォームでのテストにご協力
いただけたら嬉しいです。
Rajah のコードは Java 環境 1.1+ であれば、どこでも実行できるように
設計しましたが、テストは 1.2 か、それ以降でしか行なっていません。
少なくとも第1回の反復では、1.2 以前の Java 環境をサポートするとは
主張しようと思いません。
3. 設計
----------------------------------------------------------------------------
あらゆる設計上の決断に影響を及ぼす主要な因子の一つには、
Java 側のインターフェイスをできる限り透明に保っておきたい
というものがあります。
JFrame を開くコードはこのような感じ:
require 'Rajah'
frmCls = Java.forName('javax.swing.JFrame')
frame = frmCls.new("Example")
frm.pack
frm.show
このセクションの残りでは、Rajah の Ruby to Java インターフェイス設計の
大枠を述べます。
Rajah ライブラリには、"Java" という名前のモジュールが導入されます。
このモジュールは Java の機能をカプセル化します。その中には、Java の
クラスをロードするメソッドも含まれます。いったん何か Java のクラスが
Rajah によって Ruby にロードされると、そのクラスは Ruby のクラスとして
取り扱うことができ、メソッド呼び出し、reflection、サブクラス化、その他
Ruby のクラスでできることは何でもできるようになります。
Java のクラスのロード
Rajah の一番基本的な能力は、
Java のクラスをメモリにロードし、それらに Ruby 言語の枠内で
Ruby のクラスとして触れるようにしていることです。
このプロセスは、以下のような基本ステップを踏みます。
+ Java のクラスを見つけます。
+ Java のオブジェクトの上位クラス(super class)をロードします。
+ そのクラスを Ruby に登記します。
+ 公開の(public)コンストラクタすべてに対して、Java のクラスを
「内省」します。
【"introspect" = 内省する、内観する≒自覚+内面を客観視する】
+ 公開のメソッドすべてに対して、Java のクラスを「内省」します
(クラスメソッドもインスタンスメソッドも両方とも)。
+ 公開のフィールドすべてに対して、Java のクラスを「内省」します
(クラスフィールドもインスタンスフィールドも両方とも)。
これらのステップをこまかく見て行きましょう。
+ Java のクラスを見つけます
Ruby にクラスをロードするために、埋め込まれた仮想マシンが Java クラスを
見つけられるようでなければなりません。正確にクラスを見つけるために、
完全に適切なクラス名を提供しなければなりません("java.lang.String"など)。
その後、classpath がクラスを探します。見つからなければ、例外が投げられる
ことになります。
+ Java のオブジェクトの上位クラスをロードします
適切に Ruby に Java のクラスをロードするためには、まず、そのスーパー
クラスがロードされなければなりません。Java オブジェクトのスーパークラス
をロードしようと試みられます(これは再帰的なプロセスで、クラス階層の
頂点に到達したところで止まります)。
+ そのクラスを Ruby に登記します
Ruby への Java クラスの登記は、新しく、直接 Java クラスを参照する
ような Ruby のクラスを作成することを含んでいます。
もしそこで Java のオブジェクトがスーパークラスを持たないようなとき
(すなわちそれが "java.lang.Object" オブジェクトであったとき)、
新しい Ruby のクラスは、オブジェクト Java::JavaObject のスーパークラス
により作成されます。そうでないときは、新しい Ruby のクラスは、
Java のスーパークラスを Ruby で表現したもののスーパークラスで作成されます
(それらは Ruby で登録済みに違いないのです。なぜなら、Java クラスの登記
作業ができる前には、スーパークラスをロードしていなければならないので)。
ひとつ注意してください。クラスが Ruby に最初に登録される場合、
Java のコンストラクタ、メソッド、あるいはフィールドのいずれも、
Ruby に直ちに加われるわけではありません。
クラスが Ruby に登録されるまでは
(Rajah によってロードされてクラスが終了される前に、ですが)、
Java クラスの「内省」はなされません。
+ 公開のコンストラクタすべてに対して、Java のクラスを「内省」します
その後、公開アクセスされうる(publicly accessible)コンストラクタのすべてに
対して、Java クラスを「内省」します。
これらのコンストラクターは、Java クラスのインメモリ表現に加えられます。
最初のコンストラクタがクラスに加えられたときに、そのクラスに、
可変数パラメータを備えた "initialize" メソッドが加えられます。
Rajah によってロードしたすべてのクラスに対するすべてのコンストラクタは、
"initialize"メソッドを扱うために、C 関数コールバックを共有します。
くわしくは、オブジェクト生成についてのセクションを参照してください。
+ 公開のメソッドすべてに対して、Java のクラスを「内省」します
その後、公開アクセスされうるメソッドのすべてに対して、Java クラスを
内省します。
これらのメソッドは、Java クラスのインメモリ表現に加えられます。
Rajah によってロードしたすべてのクラスのあらゆるメソッドは、
メソッドを扱うために、C 関数コールバックを共有します。
くわしくは、メソッドについてのセクションを参照してください。
+ 公開のフィールドすべてに対して、Java のクラスを「内省」します
その後、公開アクセスされうるフィールドのすべてに対して、Java クラスを
内省します。
オブジェクトの作りかた
オブジェクトは Ruby の中で、クラスの特異メソッド "new" によって作成
されます。Java オブジェクトが Ruby に登記される際には、特異メソッド
"new" のハンドラが一つ登記されます。新しいメソッドが起動される場合、
Java クラスの新しい Java オブジェクトが生成されます。しかしながら、
コンストラクタは直ぐには起動されません。JNI を使うことで、Rajah は、
コンストラクタが一つも呼び出されていない Java オブジェクトを生成できる
ようになっています。というわけで、オブジェクトの構築は先延ばししましょう。
新しい Java オブジェクトが生成された後、それは Ruby のオブジェクトで
包まれます(wrapped)。その後、初期化メソッドは、新しいメソッドが起動
されたのと同じパラメータで呼び出されます。メソッド呼び出しについて、
詳しくは、次のセクションを参照してください。初期化メソッドは、新しい
メソッド中で作成された Java オブジェクト上の適切なコンストラクタを
起動します。コンストラクタと一致しないことが見つかる場合、与えられた
Ruby の引き数を使用して、例外が生成されます。
メソッド
Java のメソッドが Ruby でどう扱われるかの詳細をつっつく前に、それに
対する要請のいくつかを見ておきましょう:
+ Java クラスに対するクラスメソッドとインスタンスメソッドのサポート。
+ オーバーロードされた Java メソッドのサポート。
+ 軽量の呼び出しインターフェースのサポート
(Java メソッド呼び出しのオーバーヘッドはなるべく小さい方がいいですから)。
Ruby に登記された Java のメソッドはすべて、
メソッドを処理するために可変長の引き数リストを使用します。
これは以下のいくつかの目的に役立ちます:
1. すべてのクラスのあらゆるインスタンスメソッドが、同じ C の函数を使って
メソッド操作できるようにできます。
これによりコードの複雑さは最小限となり、C の API を単純に保てます。
同様に、すべてのクラスのあらゆるクラスメソッドは、
メソッドを扱うために別の C の函数を使用することができます。
2. オーバーロードされた Java メソッドをサポートできるようにします。
3. どうせ内部的には、パラメーターは配列へ包んでしまうことになるのだから、
こうすることでパフォーマンスが目に見えて悪くなることはありません。
メソッドを呼び出すプロセス
メソッドが呼び出されるときには、以下のステップを踏んでゆきます:
+ 呼び出されたメソッドの名前が検索されます。
+ メソッドの呼び出された Java クラスの中で、名前、引き数の数、静的か
そうでないかの基準、そして引き数の型が一致するメソッドがないかと
捜索がかかります。
すべての基準と一致するメソッドが見つからない場合、例外が上げられます。
+ Ruby の引き数は対応する Java パラメーターへ整列(marshal)させられます
(以下を参照)。
+ Java メソッドは JNI によって起動されます。なにか Java からの例外が
生じた場合、Ruby において対応する例外が生成され上げられます。
+ その後、メソッド呼び出しの返り値は Ruby オブジェクトへ逆整列(unmarshal)
され、メソッド呼び出しから戻されます。
Ruby の型を Java の型に map する規則
Java メソッドあるいはコンストラクタが、Ruby の引き数を使って起動される場合、
引き数は適切な Java プリミティヴあるいはオブジェクトに変換されなければ
なりません。このプロセスを、われわれは「整列させる(marshaling)」と呼びます。
同様に、メソッド(メソッドが void を返すようには宣言されない場合)の返り値は、
適切な Ruby のオブジェクトに変換されなければなりません。
このプロセスを、われわれは「逆整列させる(unmarshaling)」と呼びます。
Java は、marshaling プロセスおよび unmarshaling プロセスのために
検査される必要のある、基本的に異なる2つの実体を提供します: それが
プリミティヴとオブジェクトです。
Java 言語には 8タイプのプリミティヴがあります:
+ boolean (値は Java の予約語で "true" と "false")
+ byte (符号付き 8 ビット整数)
+ char (16 ビットの Unicode キャラクタ)
+ short (符号付き 16 ビット整数)
+ int (符号付き 32 ビット整数)
+ long (符号付き 64 ビット整数)
+ float (符号付き 32 ビット浮動小数点数)
+ double (符号付き 64 ビット浮動小数点数)
これらのプリミティヴは、Rajah によって、Ruby の値を正確に Java へ写像し、
同様に Ruby に Java の値を写像して戻すように処理されます。
Java では、すべてのオブジェクトが(陰に日向に)
Java クラス "java.lang.Object" の拡張となっています。
この規則の唯一の例外は "java.lang.Object" クラスそれ自身です。
このクラスにはスーパークラスがありません。
プリミティヴとオブジェクトの取り扱いは、Ruby の内部から明らかに透明に
なっているべきです。しかしながら、
オーバーロードされたメソッド、またはコンストラクタに直面したときには、
Rajah で marshaling もしくは unmarshaling を写像する規則を熟知している
必要があります。
Marshaling
個々のパラメーターそれぞれの marshaling は、最初のパラメーターから順々に、
連続して生じます。
(実際の marshaling が一つでも起こる前にメソッドは一致(match)するので、
marshaling のプロセスの間中にエラーがそんなに起こってはならないこと
には注意してください。)
パラメーター の Java での型が検査されて、Ruby の値は適切な Java の型へ
marshaling されます。
与えられた Java の型に対する marshaling 規則のリストは以下の通り:
+ boolean - Ruby の "true" は Java の "true" に、"false" は "false" に
写像される。
+ byte - 値が -128 〜 127 の範囲の Fixnum。
+ char - ???
+ short - 値が -32768 to 32767 の範囲の Fixnum。
+ int - 値が -2^31 to (2^31 - 1) の範囲の Fixnum もしくは Bignum。
+ long - 値が -2^63 to (2^63 - 1) の範囲の Fixnum もしくは Bignum。
+ float - 適切な値の範囲の浮動小数点数。
+ double - 適切な値の範囲の浮動小数点数。
+ java.lang.String オブジェクト - Ruby の文字列オブジェクトは、
java.lang.String オブジェクトに marshaling されます。当然ながら、
java.lang.String のオブジェクトもまた受け入れ可能です。
+ 配列(array) - Ruby の配列は Java の配列に marshaling されます。
しかし、Ruby の配列中の値が何でありうるかには制限があって、
marshaling が配列中のすべての要素に適切に生じるようでなければ
なりません。
Unmarshaling
Java から返された unmarshaling の値(起動されたメソッドからの返り値に
よるものか、フィールド・アクセスからのものかのいずれか)は、
Ruby のオブジェクトに Java オブジェクトを写像するものです。
返り値の型が Ruby にまだロードされていない Java クラスである場合、
Rajah は、上にあらましを述べた返り値に対する
クラスをロードするプロセスをこまかく見返します。
このセクションは、Rajah のドキュメントに詳述されるでしょう。
4. 横田わる問題 (順不同)
----------------------------------------------------------------------------
- 配列のサポートが完全ではありません。
- いまのところ、"initialize" に関する名前衝突のおそれがあります。
"initialize"名の Java メソッドと、Java クラスのそれぞれに定義された
定義済み "initialize" メソッドとが Ruby にロードされたときにです。
いまは"initialize"名の Java メソッドがロードされたときには何の特別な
チェックも行いません。そこで定義済みの initialize メソッドを伴うクラスを
ロードしようとしたときには、結果は未定義となります。
- Java からの例外を完全にはサポートできていません。
- Java では、throw できる型 (java.lang.Throwable オブジェクト) は
java.lang.Object の拡張となります。
しかるに Ruby では、通例によれば、例外を生み出すことは
Exception クラスの拡張となります。
もし私たちがなんとかして Ruby の Exception クラスを拡張して、
Java の throw できるオブジェクトまるっきりを用意すれば、
そりゃぁいいことでしょう。しかしながら、技術的には、throw できる
オブジェクトは java.lang.Object クラスを拡張するべきなのです。
Exception を拡張しないでオブジェクトを投げるのは、Ruby では
「よくない」やりかたなんでしょうか?
- Java インターフェースを実装する Ruby オブジェクトをサポートしようと、
吟味はしてきましたが、いまのところは実装されていません
(しゃれのつもりはございません)。
オブジェクトにランタイム・インターフェイス(プロキシ)を導入する
JDK 1.3 とともに、この問題は、部分的には和らぐかもしれません。
しかしながら、おそらくこのアプローチであっても、Java で書かれた
助手クラス(helper class)が必要になるでしょう。
- 抽象クラスはどうしましょうか? 抽象メソッドは?
抽象クラスがロードされたときの振る舞いを決めなければなりません。
- Java インターフェイスはどうしましょう?
- Java コンストラクタがクラス中になかった場合、クラスを内省した
ところで、パラメータ無しの公開コンストラクタを1つ与えましょうか?
そうでなければ、自分たちで1つ分を供給するようにするべきでしょうか?
- Ruby で、大文字あるいは_を頭文字にするメソッドはどう扱いましょうか。
- Ruby で、小文字から始まるクラスはどう扱いましょうか。
- Java クラスの中に見つけられなかったメソッドが呼び出されたとき、
スーパークラス上でメソッドを直接起動しようと試みるべきでしょうか?
そんなことは必要ありませんか?
- 現在のところ、ロードされるのは公開のメソッド/フィールドだけです。
Ruby のクラスが java クラスのうちの1つをサブクラス化してして、
そこで保護されたフィールドにアクセスしたい場合に、
protected メソッド/フィールドもロードしたいと思いますか?
これは reflection API であっても出来ないことかもしれませんが、
われわれが研究しておくべきものではあります。
- Ruby にロードされた Java クラスをサブクラス化することは、現在のところ
サポートできません。
- Java のメソッド "String toString()" を Ruby の "to_s" に写像できる
ようにしなければいけません。
(以上)