メソッドのフック
Posted feedbacks - PostScript
PostScript です。 なんか、もっと簡単に書く方法がありそうな。 TestFunction, EnterFunction, LeaveFunction が定義されているとして、 /TestFunction (Label) /EnterFunction /LeaveFunction AddHook のようにして使用します。(ネスト可) 外すときには /TestFunction RemoveHook で、TestFunction に関して最後に指定したものから1段階外れます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | %!PS
/HookExec { % {Function} (Memo) {EnterFunction} {LeaveFunction} HookExec -
2 index 3 -1 roll cvx exec
currentdict /HookFunctions-temp known not
{
/HookFunctions-temp [] def
} if
HookFunctions-temp aload length dup
3 add -2 roll
3 -1 roll 2 add array astore
/HookFunctions-temp exch def
cvx exec
HookFunctions-temp aload length 2 sub 3 1 roll cvx
exec
array astore
/HookFunctions-temp exch def
} bind def
/AddHook { % {Function} (Memo) {EnterFunction} {LeaveFunction} AddHook -
currentdict 4 index known
{
currentdict 4 index get
4 1 roll
currentdict exch 2 copy known {
get cvx
} {
cvx exch pop
} ifelse
exch
currentdict exch 2 copy known {
get cvx
} {
cvx exch pop
} ifelse
exch
/HookExec cvx
% /TestLoop2 {Func} (Memo) {Enter} {Leave}
5 array astore
% /TestLoop2 [ ]
cvx currentdict 3 1 roll put
} {
(Can't hook ) print pop pop print ( / ) print =
} ifelse
} bind def
/RemoveHook { % /Function Name RemoveHook
dup currentdict exch known
{
dup currentdict exch get
dup length 5 eq {
dup 4 get /HookExec eq {
0 get
def
} {
(Remove Hook: Invalid data ) print pop =
} ifelse
} {
(Remove Hook : Ignored ) print pop =
} ifelse
} {
(Remove Hook : Unknown Operator) print =
} ifelse
} bind def
% ----------------- Test Code ----------------
/EnterHook { % (Label) EnterHook -
(Enter: ) print dup =
currentdict /ProfilingTimer known not {
/ProfilingTimer 10 dict def
} if
ProfilingTimer exch 2 copy known {
get
} {
[0 0] dup 4 1 roll put
} ifelse
1 usertime 1000 div put
} bind def
/LeaveHook { % (Label) LeaveHook -
(Leave: ) print dup print ( : ) print
currentdict /ProfilingTimer known {
ProfilingTimer exch 2 copy known
{
get
aload 3 1 roll
usertime 1000 div sub neg
dup 10 string cvs print ( sec Total =) print
add
dup 10 string cvs print ( sec) =
0 exch put
} {
pop pop
} ifelse
} {
pop
} ifelse
} bind def
/TestLoop2 { % Count TestLoop2 -
10000 mul {
1000 {
} repeat
} repeat
} def
/TestLoop { % - TestLoop -
0 1 5 {
TestLoop2
} for
} def
/TestLoop2 (Loop2) /EnterHook /LeaveHook AddHook
% 2nd level hook
/TestLoop2 (Loop2) {(Enter ) print =} {(Leave ) print =} AddHook
/TestLoop (Loop) /EnterHook /LeaveHook AddHook
TestLoop
%Remove top level hook
/TestLoop2 RemoveHook
TestLoop
|


todogzm
#6017()
Rating0/8=0.00
例えば、あるクラスのあるメソッドを実行する前に他の処理を呼びたい(例えばログやトランザクション開始など)。 また、そのメソッドの終了後にも何らかの後処理を呼びたい(トランザクション終了など)。
そのような、メソッドに対するフック処理を書いてください。 ライブラリを使用してメソッドのフックを実現した場合は ライブラリの名前を紹介してくれると助かります。
[ reply ]