Richard,
I assume in ClassA, method b a specific call of #x has to be replaced by #z.
Thus oldSelector #x has to become newSelector #z, the call to be patched takes place in ClassA>#b. So
ClassA>>b
self x
becomes
ClassA>>b
self z
Patching the call of a method has the benefit to be reversable. You can reverse your modification if you run this with x z parameter exchanged. Here the method doing this patch
replaceSelector: oldSelector by: newSelector inClass: callingClass method: callerSelector
"Replace old selector by a new selector in a method of a class"
| cm original |
cm := (original := callingClass compiledMethodAt: callerSelector) emDecodableMethod.
cm filePointer: original filePointer.
cm methodClass methodDictionary add: cm.
cm markReadOnly: false.
[1 to: cm literalSize do: [:i | (cm at: i) = oldSelector ifTrue: [cm at: i put: newSelector]]]
ensure: [cm markReadOnly: true]
An example in using this
self replaceSelector: #x by: #z inClass:
ClassA
method: #b
Undoing this
self replaceSelector: #z by: #x inClass:
ClassA
method: #b
I apply this in the development image. Packaging the patched method is untested. That means, it depends wether the original call or the patched call is packaged. in the latter case, the patch has to be redone at runtime.
Kind regards
M