Curlでのリフレクションの使用方法について記載していきます。そもそもリフレクションとはCurlのクラスからメソッドやゲッターの情報を取得するAPIのことです。また、取得したメソッド等を実行することができます。
リフレクションを利用するためには、CURL.LANGUAGE.REFLECTIONというパッケージをインポートする必要があります。
{import * from CURL.LANGUAGE.REFLECTION} |
まず当機能を説明するにあたって以下のクラス(Foo)を例にとっていきたいと思います。
{curl 6.0 package} {define-class public open Foo field private _a:String {getter public {a}:String {getter public {b}:int {constructor public {default {method public open {display}:void {dump self._a, self._b} |
文字列からインスタンス作成
文字列のパッケージ名やクラス名からオブジェクトを生成する方法を下のソースコードをもとに説明していきます。
文字列(”COM.CURLAP.TEST”)から、Packageクラス(パッケージのクラスです。)のオブジェクトを生成するため、ComponentSelectorを利用します。この生成されたPackageオブジェクトから、その中に含まれるクラスやプロシージャを取得するため、get-memberメソッドを文字列のクラス名(”Foo”)を指定して実行します。get-memberメソッドはPackageMemberをかえします。
このPackageMemberのget-valueを利用し、ClassTypeクラスのオブジェクトを取得します。そのClassTypeからget-constructorを用いてConstructorを取得できますので、newメソッドを利用し、Fooクラスのオブジェクトを生成できます。
|| Package let p:Package = {import-package {ComponentSelector name = “COM.CURLAP.TEST”} } || PackageMember let m:#PackageMember = {p.get-member “Foo”} || ClassType || Constructor || オブジェクトの生成 |
オブジェクトからクラス名等の名前を取得
オブジェクトからクラス名やメソッド名、ゲッター・セッター名等を取得する方法を下のソースコードをもとにご説明します。
最初に、Fooオブジェクトを通常通り生成します。このFooオブジェクトのゲッターとメソッドの情報をリフレクションを利用し、取得することとします。
リフレクションの利用にあたってまずはFooオブジェクトのClassTypeオブジェクトをtype-ofマクロを用いて取得します。パッケージ名を取得するには、このClassTypeオブジェクトのpackage.nameアクセッサーを利用することで取得できます。次のゲッターやメソッドを取得するため、ClassType.get-membersメソッドを利用します。この際、ゲッターならClassMember.getter-filterをメソッドならClassMember.method-filterをキーワード引数のfilterに指定します。これによりすべてのゲッター名やメソッド名を取得することができます。
また、上記で取得した名前を元に、{ClassType.get-getter ゲッター名}でGetterオブジェクトを取得し、そのget-valueメソッドで値を主時できますし、{ClassType.get-method “メソッド名”}でMethodオブジェクトを取得し、invokeメソッドでメソッドを実行することができます。
let foo:Foo = {Foo “foo-foo-foo”, 1234} || getter || method |
もちろんその他、セッターやプロシージャ等々の情報も取得し、実行することができます。
関連ドキュメント