unom
unom

Reputation: 11476

Refactoring methods and creating copies with a different name in Pharo Smalltalk?

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

Answers (1)

Peter Uhnak
Peter Uhnak

Reputation: 10207

You can compile methods by sending a compile: message to the target class.

  1. retrieve the method
    • e.g. method := Float>>#cos or method := Float methodNamed: #cos
  2. retrieve the source code

    • method sourceCode will return the method code as a string
    • method ast (or method parseTree) will return the code as parsed tree representation
  3. Compile code into a class (optionally with protocol)

    • TargetClass compile: sourceCode, or
    • TargetClass 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.

Using AST

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

Related Questions