2014-01-20 51 views

回答

2

菲羅4將有一個解決方案,但現在你必須做手工......

對於像#+,#正常的消息 - 等等......你可以修改文字陣列但它不能用於#ifTrue:ifFalse:和#ifFalse:ifTrue之類的消息:因爲編譯器將代碼內聯以獲得更好的性能。一種解決方案是複製方法的AST,修改它,編譯它並將其安裝到類中。這樣的東西應該工作:

FaultInjector>>#replace: aSelector with: anotherSelector in: aCompiledMethod 
    | newAST | 
    "Save the original method to restore it later" 
    replacedMethods add: aCompiledMethod. 

    "Copy the AST" 
    newAST := aCompiledMethod ast copy. 

    "Rewriting the AST" 
    newAST nodesDo: [ :each | 
     (each isMessage and: [ each selector = aSelector ]) 
      ifTrue: [ each selector: anotherSelector ] ]. 

    "Compile the AST and install the new method" 
    aCompiledMethod methodClass 
     addSelectorSilently: aCompiledMethod selector 
     withMethod: (newAST generate: aCompiledMethod trailer). 

那麼你應該有恢復您更換方法的方法:

FaultInjector>>#restore 
    replacedMethods do: [ :each | 
     each methodClass 
      addSelectorSilently: each selector 
      withMethod: each ]. 
    replacedMethods removeAll 
+0

作品在菲羅3搜索MutationEngine,是非常酷!謝謝! (在Pharo 2中,RBMethodNode還不理解#generate:但這只是一個提示,我對Pharo 3很好) – MartinW

相關問題