gpt4 book ai didi

smalltalk - 如何在 Smalltalk 中在运行时向类添加方法?

转载 作者:行者123 更新时间:2023-12-04 11:44:22 31 4
gpt4 key购买 nike

我正在为基于 XML 的 Web 服务构建 Smalltalk API。 XML 服务非常规则,我想与其手动编写方法,不如覆盖 #doesNotUnderstand:通过 MyApi class>>compile: 动态添加方法,然后在工作区中调用一次所有方法,然后删除 DNU 并拥有我不错的 API。

这很好用,但是将一个巨大的字符串传递给 #compile:只是觉得我很不对;在 Python 和其他语言中,我可以将一个经过良好语法检查的 lambda 附加到一个类中,以更安全的方式实现类似的效果。例如。:

def himaker(name):
def hello(self, times):
for x in xrange(times):
print "Hi, %s!" % name
return hello
class C(object): pass
C.bob = himaker('Bob')
C.jerry = himaker('Jerry')
a = C()
a.bob(5)

相对
SomeObject>>addHello: name
| source methodName |
methodName := 'sayHello', name, 'Times:'.
source := String streamContents: [ :s |
s nextPutAll: methodName, ' count'.
s nextPut: Character cr.
s nextPut: Character tab.
s nextPutAll: 'count timesRepeat: [ Transcript show: ''Hi, ', name, '!'' ].' ]
SomeObject class compile: source

肯定有像 Python 版本一样干净的东西吗?

最佳答案

如果您只是希望源字符串更清楚地反射(reflect)方法:

SomeObject>>addHello: name
| methodTemplate methodSource |
methodTemplate := 'sayHello{1}Times: count
count timesRepeat: [ Transcript show: ''Hi, {1}!'' ].'.
methodSource := methodTemplate format: { name }.
self class compile: methodSource.

如果您希望对源代码进行语法检查,您可以从这样的模板方法开始:
sayHelloTemplate: count
count timesRepeat: [ Transcript show: 'Hi, NAME' ].

然后相应地填写模板,例如:
addHello2: name
| methodTemplate methodSource |
methodTemplate := (self class compiledMethodAt: #sayHelloTemplate:) decompileWithTemps.
methodTemplate selector: ('sayHello', name, 'Times:') asSymbol.
methodSource := methodTemplate sourceText copyReplaceAll: 'NAME' with: name.
self class compile: methodSource.

当然,如果提取一些方法,所有这些都会更清楚:)

关于smalltalk - 如何在 Smalltalk 中在运行时向类添加方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4460991/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com