かんだです。


  すぐにではないんですが、Ruby/CORBA で Rubyスクリプトから IDL の生成をや
るつもりです。IDL というのは C++ のサブセット風の言語で、インターフェース
のみを記述するものです。例えばこんな感じです。

interface String {
  String crypt(in String salt);
};

  CORBA実装ではこれを処理してサーバーやクライアントのスタブコードを生成
するので、IDLの扱いはほとんど必須です。
  サーバー開発者は IDL も提供しないといけないんですが、いちいち IDL で
書くのは面倒というのがあって、例えば Java コードから IDL の生成は定めら
れてます(見てないんで詳しいところは分からないですが)。

  あとまだ構想ですが、動的に IDL を読んでスタブを作ってオブジェクトに
extend するとかいうことも考えてます。それならいちいち IDL を解析するより
も .rb で記述されているのがあればそっち使っちゃえ、と思いますよね。
# どっちかというとこちらの方が理由は強い。カッコいいゾ:-)

  というわけで、Ruby スクリプトで IDL と同等のことを記述したいのですが、
先ほどの例を見て分かる通り、例えば型などは Ruby の文法では情報が足りませ
ん。まだ typedef とか enum どうしようとかもあるんですが、とりあえず、メ
ソッド宣言文を加えてくれませんか?

  def を色々拡張するというのも考えましたが、それよりも宣言専用の構文を
導入した方が互換性などもいいと思いますので、こんなのはどうでしょう?

class A
  dcl void foo()
  def foo(); end

  dcl String str()
  def str()
    return "Hello, World"
  end

  dcl String test(in Integer i)
  def str(i)
    i.to_s
  end
end

  dcl文の追加。dcl は予約語扱いになるのかな。
  冗長なので def 文を省略できた方がいいかもしれないです。


  ちなみに次のようなモジュールでも同様のことはできますが、とてもじゃな
いですが受け入れ難い構文です(^^;

--------------------------------------------------------------------
module IDL
  def IDL.extend_object(obj)
    ret = super
    obj.instance_eval <<EOF

    @methods = Hash::new
    def declared_methods
      return @methods
    end
    def declared_method(name)
      return @methods[name]
    end
EOF

    return ret
  end

  def dcl(*args)
    mname = args.shift

    ret = nil
    params = []
    iparams = []
    oparams = []
    args.each do |param|
      io, type, name = *param

      if io == :ret
	ret = [type, name]
      else
	params << [io, type, name]
      end

      case io
      when :inout
	iparams << [type, name]
	oparams << [type, name]
      when :in
	iparams << [type, name]
      when :out, :ret
	oparams << [type, name]
      end
    end
    @methods[mname] = [ret, params, iparams, oparams]
  end
end


class A
  extend IDL

# void foo()
  dcl :foo, [:ret, nil]

# String str()
  dcl :str, [:ret, String]

# String test(in Integer i)
  dcl :test, [:ret, String], [:in, Integer, :i]
end

p A.declared_method(:foo)
p A.declared_method(:str)
p A.declared_method(:test)
--------------------------------------------------------------------