Как мне динамически изменить имя метода в писк? - PullRequest
1 голос
/ 19 мая 2009

У меня есть класс, и я хочу изменить имя определенного метода во время выполнения. Я думаю, что есть метод в классе «Поведение», который делает это. Но я просто не могу его найти. любая помощь? [в писк]

Ответы [ 5 ]

2 голосов
/ 20 мая 2009

То, что вы предлагаете, ставит ОГРОМНЫЕ красные флаги для меня. Что вы пытаетесь достичь с этим?

Вы имеете в виду, что хотите изменить имя метода, который вы вызываете во время выполнения? Если так, то это просто.

сделать что-то вроде:

|methodName|
methodName :=  self useMethod1 ifTrue: [#method1 ] ifFalse:[ #method2 ].
self perform: methodName.
2 голосов
/ 19 мая 2009

Обычный способ сделать это - изменить источник метода и «принять его», а затем удалить старую версию. Так что маловероятно, что базовый Squeak включает в себя единственный способ сделать это, хотя я могу ошибаться.

Однако, если вы, например, устанавливаете OmniBrowser, существует метод рефакторинга под названием «переименование», и вы можете проверить и найти код для выполнения этого рефакторинга. Это довольно сложно, во-первых, потому что рефакторинг выполняется с использованием шаблона команды, который требует небольшого перенаправления, но во-вторых, потому что это довольно сложный рефакторинг, который включает в себя изменение сайтов вызовов.

1 голос
/ 20 декабря 2009

Лучше всего использовать рефакторинг

r := RenameMethodRefactoring 
    renameMethod: #foo:foo: 
    in: Foo
    to: #bar:bar:
    permutation: (1 to: #foo:foo: numArgs). 
r execute.
0 голосов
/ 01 мая 2011

На самом деле вы не можете изменить имя метода, потому что у него его нет.

Словарь методов объекта отображает символы в CompiledMethods. «Изменить имя метода» означает «переместить значение CompiledMethod из этого ключа в этот ключ».

0 голосов
/ 18 декабря 2009

Избегайте магии вуду в реальном коде, когда это возможно.

При этом вы можете делать очень интересные вещи, динамически манипулируя методами.

Например, кодовые блоки в 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 немного дольше, чем я.

...