| 要約: | - 実行時に Curl プログラムの構造をインスペクトして使用します。
|
Curl® リフレクション インターフェイスをプログラムで使用すると、Curl プログラムを実行時にインスペクトして使用するデータとして扱うことができます。これは Curl パッケージの public 属性の機能へのアクセスを提供し、現時点では、private と package 機能にはリフレクション インターフェイスを使ってアクセスできません。プログラムでは、デバックの際にリフレクションを使用したり、コンパイル時に不明のコードに対し、対話型あるいはデータドリブンのインターフェイスを提供する目的でこれを使用できます。
注意: リフレクション インターフェイスを使い、このインターフェイスについて学ぶこともできます。
| 例:
Package およびインポートされたパッケージへのアクセス |
 |
{value
let current:VBox = {VBox}
{current.add
{HBox
|"{get-current-package} : "|,
{String {get-current-package}}
}
}
let imports:VBox = {VBox}
{for p in {get-current-package}.imported-packages do
{imports.add {String p}}
}
{current.add
{HBox
|"{get-current-package}.imported-packages : "|,
imports
}
}
current
}
| |
| 例:
パッケージを名前で選択 |
 |
{value
let p:Package =
{import-package
{ComponentSelector name = "CURL.LANGUAGE.REFLECTION"}
}
let members:VBox = {VBox}
{for m in {p.get-members} do
{members.add {String m}}
}
{VBox
{HBox
{String p & ".get-members : "},
members
}
}
}
| |
| 例:
名前で PackageMember を選択 |
 |
{import * from CURL.LANGUAGE.REFLECTION}
{value
let p:Package =
{import-package
{ComponentSelector name = "CURL.LANGUAGE.REFLECTION"}
}
let m:#PackageMember =
{p.get-member "PackageMember", check-imports? = false}
{table
{row
{cell {String m & ".access"}}
{cell {String m.access}}
}
{row
{cell {String m & ".constant?"}}
{cell {String m.constant?}}
}
{row
{cell {String m & ".name"}}
{cell {String m.name}}
}
{row
{cell {String m & ".package"}}
{cell {String m.package}}
}
{row
{cell {String m & ".public?"}}
{cell {String m.public?}}
}
{row
{cell {String m & ".type"}}
{cell {String m.type}}
}
}
}
| |
| 例:
PackageMember の使用 |
 |
{import * from CURL.LANGUAGE.REFLECTION}
{value
let p:Package =
{import-package
{ComponentSelector name = "CURL.RUNTIME.PROCESS"}
}
let m:#PackageMember = {p.get-member "get-current-package"}
{table
{row
{cell {String m & ".access"}}
{cell {String m.access}}
}
{row
{cell {String m & ".constant?"}}
{cell {String m.constant?}}
}
{row
{cell {String m & ".name"}}
{cell {String m.name}}
}
{row
{cell {String m & ".package"}}
{cell {String m.package}}
}
{row
{cell {String m & ".public?"}}
{cell {String m.public?}}
}
{row
{cell {String m & ".type"}}
{cell {String m.type}}
}
}
}
| |
| 例:
PackageMember 使ってプロシージャを呼び出す |
 |
{import * from CURL.LANGUAGE.REFLECTION}
{value
let p:Package =
{import-package
{ComponentSelector name = "CURL.RUNTIME.PROCESS"}
}
let m:#PackageMember = {p.get-member "get-current-package"}
{assert m.type == {type-of get-current-package}}
{assert {m.get-value} == get-current-package}
{assert {{m.get-value}} == {get-current-package}}
{table
{row
{cell direct}
{cell reflection}
}
{row
{cell get-current-package}
{cell {String m.name}}
}
{row
{cell {type-of get-current-package}}
{cell {String m.type}}
}
{row
{cell {value get-current-package}}
{cell {m.get-value}}
}
{row
{cell {get-current-package}}
{cell {{m.get-value}}}
}
}
}
| |
| 例:
ClassMember のクラス メンバを調べる |
 |
{import * from CURL.LANGUAGE.REFLECTION}
{value
let t:ClassType = ClassMember
let members:Table =
{Table
{row-prototype
{cell-prototype t}
},
{row-prototype
{cell-prototype "member"},
{cell-prototype "name"}
}
}
{for m in {t.get-members search-superclasses? = false} do
{members.add
{row-prototype
{cell-prototype m},
{cell-prototype m.name}
}
}
}
members
}
| |
名前に
-filter を含むクラス プロシージャは、クラスで特定の種類の機能を探し出すという便利な方法を提供します。たとえば、次のコードでは
Table クラスで直接実装されているオプションを検索しています。
ClassMember.option-filter は
Option クラス メンバの場合には
true を返し、その他のメンバでは
false を返します。
| 例:
Table のオプションを調べる |
 |
{import * from CURL.LANGUAGE.REFLECTION}
{value
let t:ClassType = Table
let members:Table =
{Table
{row-prototype
{cell-prototype "member"},
{cell-prototype "name"},
{cell-prototype "type"}
}
}
{for m in {t.get-members
search-superclasses? = false,
filter = ClassMember.option-filter
}
do
{members.add
{row-prototype
{cell-prototype m},
{cell-prototype m.name},
{cell-prototype m.type}
}
}
}
members
}
| |
クラス変数はその名前にクラス名を付けてアクセスする変数で、実質上グローバルであり、特定のオブジェクト だけに存在するものではありません。
| 例:
ClassVariable のクラス メンバを調べる |
 |
{import * from CURL.LANGUAGE.REFLECTION}
{value
let t:ClassType = ClassVariable
let members:Table =
{Table
{row-prototype
{cell-prototype t}
},
{row-prototype
{cell-prototype "member"},
{cell-prototype "name"},
{cell-prototype "type"}
}
}
{for m in {t.get-members search-superclasses? = false} do
{members.add
{row-prototype
{cell-prototype m},
{cell-prototype m.name},
{cell-prototype m.type}
}
}
}
members
}
| |
リフレクションを使ってクラス変数の値を取得および設定する方法を次に示します。
|
|
| let v = {cv.get-value} |
| {cv.set-value v} |
|
|
|
| cv | ClassVariable。 |
| v | cv.type 型の値。 |
|
| 例:
Property のクラス メンバを調べる |
 |
{import * from CURL.LANGUAGE.REFLECTION}
{value
let t:ClassType = Property
let members:Table =
{Table
{row-prototype
{cell-prototype t}
},
{row-prototype
{cell-prototype "member"},
{cell-prototype "name"},
{cell-prototype "type"}
}
}
{for m in {t.get-members search-superclasses? = false} do
{members.add
{row-prototype
{cell-prototype m},
{cell-prototype m.name},
{cell-prototype m.type}
}
}
}
members
}
| |
|
|
| let v = {p.get-value obj} |
| {p.set-value obj, v} |
|
|
|
| p | obj の Property。 |
| obj | p.declaring-class 型のオブジェクト。 |
| v | obj の p の p.type 型の値。 |
|
| 例:
リフレクションを使ったオブジェクト作成 |
 |
{import * from CURL.LANGUAGE.REFLECTION}
{value
let t:ClassType = String
let members:Table =
{Table
{row-prototype
{cell-prototype t}
},
{row-prototype
{cell-prototype "member"},
{cell-prototype "name"},
{cell-prototype "type"},
{cell-prototype |"{f.new 'X', 3}"|},
{cell-prototype |"{type-of {f.new 'X', 3}}"|}
}
}
{for m in {t.get-members
search-superclasses? = false,
filter = ClassMember.instance-maker-filter
} do
let f:Factory = m asa Factory
{members.add
{row-prototype
{cell-prototype f},
{cell-prototype f.name},
{cell-prototype f.type},
{cell-prototype {f.new 'X', 3}},
{cell-prototype {type-of {f.new 'X', 3}}}
}
}
}
members
}
| |
| 例:
Method のメソッドを調べる |
 |
{import * from CURL.LANGUAGE.REFLECTION}
{value
let t:ClassType = Method
let members:Table =
{Table
{row-prototype
{cell-prototype t}
},
{row-prototype
{cell-prototype "member"},
{cell-prototype "name"},
{cell-prototype "type"}
}
}
{for m in {t.get-members
search-superclasses? = false,
filter = ClassMember.method-filter
} do
{members.add
{row-prototype
{cell-prototype m},
{cell-prototype m.name},
{cell-prototype m.type}
}
}
}
members
}
| |
|
|
| 直接 : | let v = {o.f ...} | | リフレクション : | let v = {m.invoke-n o, ...} let a = {m.invoke o, ...} |
|
|
|
| o | クラス C のオブジェクト。 |
| f | C のメソッド。 |
| m | メソッド C.f を表す Method オブジェクト。 つまり、m は {t.get-method "f"} の値で、t は (C asa ClassType) になります。 |
| ... | C.f メソッドの引数。 |
|
上記の説明を次の例で実際に使ってみましょう。
| 例:
リフレクションを使ったメソッド呼び出し |
 |
{import * from CURL.LANGUAGE.REFLECTION}
{table
{row
{cell direct:}
{cell
{{String 'X', 3}.equal?
{String.repeat-char 'x', 3},
ignore-case? = true
}
}
}
{row
{cell reflection:}
{cell
{{(String asa ClassType).get-method "equal?"}.invoke
{{(String asa ClassType).get-instance-maker "default"}.new
'X', 3
},
{{(String asa ClassType).get-instance-maker "repeat-char"}.new
'x', 3
},
ignore-case? = true
}
}
}
}
| |
Copyright © 1998-2023 SCSK Corporation.
All rights reserved.
Curl, the Curl logo, Surge, and the Surge logo are trademarks of SCSK Corporation.
that are registered in the United States. Surge
Lab, the Surge Lab logo, and the Surge Lab Visual Layout Editor (VLE)
logo are trademarks of SCSK Corporation.