Transcript Get Slide
+
破壊的クラス拡張のスコープを制限する
モジュール機構の意味論およびその実装方
法+, ++
++
+
竹下 若菜,赤井 駿平,千葉 滋
+東京大学 創造情報学専攻
++東京工業大学 数理・計算学専攻
破壊的クラス拡張
+ 既存のコードを変更せずに
2
既存のクラスにメソッドの追加・再定義
コードの再利用
サブクラスに関する変更・オブジェクト生成部分
の書き換えが不必要
Windowクラス
class Window{
:
void setBorder(){
//WindowsXPの
//フレームのボーダー
}
}
win7パッケージ
Frameクラス
Dialogクラス
revise Window{
void setBorder(){
//Windows7の
//フレームのボーダー
}
}
例:ウィジェットを破壊的クラス拡張する
+
3
2種類のlook&feelを持ったアプリケーションを作る
Windows
7のlook&feelだが、ボーダーだけはこのアプリ
ケーション専用のデザイン
管理者権限認証時だけは特別なlook&feel
インストール時など
ウイルスに偽パネルを出されにくいように
多重再定義の危険
+
同じクラスに対して破壊的クラス
拡張を複数行うとメソッド名が
衝突する危険性
win7パッケージ
元クラス
class Window{
void setButtonColor(){
//WindowsXPデザイン
}
void setSize(){
・・・・
}
多重
void setBorder(){
再定義
//WindowsXPの
//フレームのボーダー
}
}
4
authenticationパッケージ
revise Window{
void setBorder(){
//管理者権限認証用の
//フレームのボーダー
}
}
revise Window{
void setBorder(){
//Windows7の
//フレームのボーダー
}
void setButtonColor(){
//Windows7デザイン
}
}
appパッケージ
revise Window{
void setBorder(){
//アプリケーションの
//フレームのボーダー
}
}
+
5
用途に応じた柔軟なスコーピング
用途に応じた柔軟なスコーピングが必要
スコーピングはメソッド名衝突を回避する方法の一つ
破壊的クラス拡張の影響範囲を制限
既存のスコーピングは固定的
Ruby: 最新の定義が有効(スコープは制限しない)
RubyのRefinements: 有効な静的スコープを指定
Classboxes: 有効な動的スコープを指定
+
提案:モジュール機構Method Shelters
6
様々なスコーピングをとることができるモジュール
機構
モジュール:シェルター
破壊的クラス拡張とrequire宣言を持つ
require宣言で他のシェルターをシェルター内に取り込むことができる
取り込んだシェルター内の破壊的クラス拡張はそのシェルターで定義した
かのように扱える
2種類のrequire
使い分けることで様々なスコーピングを可能に
動的なスコーピングの中に静的なスコーピングを実現
exposedly
requireとhiddenly require
+
exposedly
win7シェルター
revise Window{
void setBorder(){
//windows7用の
//フレームのボーダー}
void setButtonColor(){…}
void
: makeFrame(){
:
setBorder();
setBorder();
:
:
}
authenticationシェルター
revise Window{
権限認証用の
void
setBorder(){
//フレームのボーダー }
//管理者権限認証用の
void
setButtonColor(){…}
//フレームのボーダー
}
checkPass(){
void setButtonColor(){…}
:
void checkPass(){
setBorder();
:
:
setBorder();
:
}}
appシェルター
requires win7;
requires hiddenly authentication;
revise Window{
void setBorder(){
//アプリケーション用のボーダー}
void install(){
: :
checkPass();
checkPass();
: :
makeFrame();
makeFrame();
: :
}}}}}}
hiddenly
7
exposedly
require
+
win7シェルター
8
authenticationシェルター
void makeFrame(){
:
}
appシェルター
推移的なrequire
requires win7;
requires hiddenly auth;
呼び出し
:
makeFrame();
requireしたシェルター中
のメソッド定義をさらに再
定義できる
繰り返しシェルターを
requireすることでメソッ
ドを何度も再定義可能
呼び出し
update_appシェルター
requires app;
void makeFrame(){
:
}
hiddenly
require
+
win7シェルター
9
authenticationシェルター
void checkPass(){
:
}
appシェルター
非推移的なrequire
requires win7;
requires hiddenly auth;
:
checkPass();
呼び出し
requireしたメソッド定義
をさらに再定義すること
はできない
他のシェルターに影響を
与えない・影響されない
update_appシェルター
requires app;
void checkPass(){
:
}
+
10
シェルターによるスコーピング
2種類のrequireで柔軟なスコーピング
既存のスコーピングも可能
RubyのRefinements
hiddenly requireで実現可能
Classboxes
exposedly requireで実現可能
+ メソッド探索
11
ルートから探索
メソッド
呼び出し
再定義されている可能性があるため
F
D
メソッド
呼び出し
G
ここから探索
E
C
B
ここから探索
A
+ メソッド探索の実装方法
12
実行時の文脈に依存したメソッド探索
コールスタックによりパスをチェックし、呼び出すメソッド定義を決定
void update(){
setBorder(); }
<シェルター名>
<クラス名>.<メソッド名>
stdGUI
authentication
Window.setBorder
setBorderの定義
win7
authenticatio
n
app
stdGUI
Window.update
authentication
Window.checkPass
app
Window.install
コールスタック
+
13
効率の良い実装方法
コンパイル時に変更
1. コールスタックを探索せずにメソッド定義を決定できるよ
うにする
2. クラス名とメソッド名のみで探索ができるようにする
通常のメソッド探索のコストに近づける
操作的な定義を素朴に実装すると実行時間のコストがかかる
+ 効率の良い実装方法1
14
実行時にコールスタックを見る必要をなくす
シェルターのrequire関係の木構造を静的解析
コールスタックを探索せずにメソッドを決定
ノード毎に一意なメソッド定義が決定
D
D
ABD
AC
AB
B
C
A
ACD
A
+ 効率の良い実装方法2
15
クラス名とメソッド名のみでメソッド探索を可能に
一意に決定したメソッド定義のメソッド名を変更
メソッド名とメソッド定義が一対一に対応
メソッド呼び出し元も書き換える
ABDノード
変更前
void setFrame{
setBorder();
}
呼び出し
void setBorder(){
//win7のボーダー
}
ABDノード
変更後
void setFrame{
setBorder_ABD();
}
呼び出し
void setBorder_ABD(){
//win7のボーダー
}
+ 形式化
操作的な定義の形式化
16
実装方法の形式化
+ 関連研究
前身研究:Method
17
Shelters[赤井・千葉 AOSD ’12]
chamberによってシェルターの中を二つに分ける
hidden chamberとexposed chamber
chamberの中に破壊的クラス拡張とインポート宣言
インポートは一種類
形式化がない
破壊的クラス拡張は以下の言語に実装されている
Smalltalk, Ruby, AspectJ, MultiJava,GluonJ……..
Classbox/J
ClassboxesをJavaに導入した
+
18
まとめ
モジュール機構Method
Shelters
2種類のrequireで様々なスコーピングを可能に
exposedlyなrequireとhiddenlyなrequire
実装前と同コストでメソッド探索が可能な実装方
法の提案
形式化
今後の予定
実際にJavaに実装してみる