我有一个类,我想在运行时更改特定方法的名称。 我想在'Behavior'类中有一个方法可以做到这一点。但我找不到它。任何帮助? [吱吱声]
答案 0 :(得分:2)
用户执行此操作的正常方法是修改方法源并“接受”然后删除旧版本。所以基本的Squeak不太可能包含一种方法来做到这一点,尽管我可能是错的。
但是,如果您安装OmniBrowser,则会有一个名为'rename'的方法重构,您可以检查并查找执行此重构的代码。它相当复杂,首先是因为重构是使用命令模式完成的,它涉及一点重定向,但其次是因为这是一个相当复杂的重构,包括修改调用站点。
答案 1 :(得分:2)
你的建议是给我带来巨大的红旗。 你想用这个来完成什么?
您是否想要更改在运行时调用的方法的名称? 如果是这样,那很容易。
做类似的事情:
|methodName|
methodName := self useMethod1 ifTrue: [#method1 ] ifFalse:[ #method2 ].
self perform: methodName.
答案 2 :(得分:1)
您最好使用重构
r := RenameMethodRefactoring
renameMethod: #foo:foo:
in: Foo
to: #bar:bar:
permutation: (1 to: #foo:foo: numArgs).
r execute.
答案 3 :(得分: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代码的时间比我更长,您可能会找到一种更简单的方法。
答案 4 :(得分:0)
您确实无法更改方法的名称,因为它没有方法名称。
对象的方法字典将符号映射到CompiledMethods。 “更改方法的名称”表示“将CompiledMethod值从此键移动到该键”。