2

我有一个类,我想在运行时更改特定方法的名称。我猜“行为”类中有一个方法可以做到这一点。但我就是找不到。有什么帮助吗?[吱吱声]

4

5 回答 5

2

用户执行此操作的正常方式是修改方法源并“接受”,然后删除旧版本。所以基本的 Squeak 不太可能包含一个单一的方法来做到这一点,尽管我可能是错的。

但是,例如,如果您安装 OmniBrowser,则有一种称为“重命名”的重构方法,您可以检查并找到执行此重构的代码。这是相当复杂的,首先因为重构是使用命令模式完成的,这涉及到一些重定向来解决,其次因为这是一个相当复杂的重构,其中包括修改调用站点。

于 2009-05-19T17:36:21.197 回答
2

你的建议给我带来了巨大的危险。你想用这个来完成什么?

你的意思是你想改变你在运行时调用的方法的名称吗?如果是这样,那很容易。

做类似的事情:

|methodName|
methodName :=  self useMethod1 ifTrue: [#method1 ] ifFalse:[ #method2 ].
self perform: methodName.
于 2009-05-19T20:28:37.363 回答
1

你最好使用重构

r := RenameMethodRefactoring 
    renameMethod: #foo:foo: 
    in: Foo
    to: #bar:bar:
    permutation: (1 to: #foo:foo: numArgs). 
r execute.
于 2009-12-20T12:29:02.457 回答
0

尽可能避免在实际代码中使用巫术魔法。

话虽如此,您可以通过动态操作方法来做一些非常有趣的事情。

例如,Etoys 中的代码块被翻译成 Smalltalk 方法。其他DSL实现也可以从类似的元编程技巧中受益。

经过一番试验后,我想出了以下代码来重命名一元方法:

renameMethod: oldMethod inClass: class to: newMethod
| oldSelector newSelector source parser |

oldSelector := oldMethod asSymbol.
newSelector := newMethod asSymbol.
oldSelector = newSelector ifTrue: [^self].

"Get method category"
category := (LocatedMethod location: class selector: oldSelector) category.

"Get method source code"
source := class sourceCodeAt: oldSelector.

"Replace selector in method source" 
(parser := class parserClass new) parseSelector: source.
source := (newSelector asString), (source allButFirst: parser endOfLastToken).

"Compile modified source"
class compile: source classified: category.

"Remove old selector"
class removeSelector: oldSelector

如果您浏览 Squeak 代码的时间比我长一点,您可能会找到一种更简单的方法来执行此操作。

于 2009-12-18T06:31:11.533 回答
0

You can't change a method's name, really, because it doesn't have one.

An object's method dictionary maps Symbols to CompiledMethods. "Change the name of a method" means "move the CompiledMethod value from this key to that key".

于 2011-05-01T07:21:02.380 回答