Reputation: 11476
I am experimenting with refactoring and some custom functionality. Is there a way to copy a method to the same class as the original but under a new name? (essentially creating a really shallow copy) You can do this by hand by editing the method source, but can it be done programatically?
For example:
doMethodName: anArgument
^ anObject doThat with: anArgument
becomes:
doNewMethodName: anArgument
^ anObject doThat with: anArgument
Upvotes: 2
Views: 269
Reputation: 10207
You can compile methods by sending a compile:
message to the target class.
method := Float>>#cos
or method := Float methodNamed: #cos
retrieve the source code
method sourceCode
will return the method code as a stringmethod ast
(or method parseTree
) will return the code as parsed tree representationCompile code into a class (optionally with protocol)
TargetClass compile: sourceCode
, orTargetClass compile: sourceCode classified: protocol
So if you have
Something>>doMethodName: anArgument
^ anObject doThat with: anArgument
You can do
code := (Something>>#doMethodName:) sourceCode.
"replace all matches"
newCode := code copyReplaceAll: 'doMethodName:' with: 'doNewMethodName:'.
"or just the first"
newCode := code copyWithRegex: '^doMethodName\:' matchesReplacedWith: 'doNewMethodName:'.
Something compile: newCode.
sourceCode
returns the code as string, which isn't the nicest to manipulate.
If you just want to change the method name, you can rename it in the AST, e.g.
tree := (Something>>#doMethodName:) parseTree.
tree selector: 'doNewerMethodName:'.
Something compile: tree newSource.
Upvotes: 3