我正在为基于XML的Web服务构建Smalltalk API。 XML服务非常规则,而不是手工编写方法,我想我只是覆盖#doesNotUnderstand:
来通过MyApi class>>compile:
动态添加方法,然后在工作区调用所有方法一次,然后删除DNU并拥有我的API。
这很好用,但是把一根巨大的弦传递给#compile:
只是觉得我错了;在Python和其他语言中,我能够将一个很好的语法检查的lambda附加到一个类,以更安全的方式实现类似的效果。 E.g:
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版本一样干净的东西吗?
答案 0 :(得分:4)
如果您只是希望源字符串更清楚地反映方法:
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.
当然,如果提取了一些方法,所有这些都会更清楚:)
答案 1 :(得分:4)
假设您有模板方法:
SomeClass>>himaker: aName
Transcript show: 'Hi ...'
然后你可以将它复制到其他类,只是不要忘记设置选择器和类 如果你不想混淆系统浏览器。或者,如果您不在乎,只需在方法词典中安装副本。
| method |
method := (SomeClass>>#himaker:) copy.
method methodClass: OtherClass.
method selector: #boo: .
OtherClass methodDict at: #boo: put: method.
method := method copy.
method selector: #bar: .
method methodClass: OtherClass2.
OtherClass2 methodDict at: #bar: put: method.
答案 2 :(得分:0)
好吧,编译:接受一个字符串。如果你想要更安全的东西,你可以构建一个parsetree并使用它。
答案 3 :(得分:0)
我会使用block:
himaker := [:name | [:n | n timesRepeat: [Transcript show: 'Hi , ', name, '!']]]
hibob = himaker value: 'bob'.
hialice = himaker value: 'alice'.
hialice value: 2
你仍然可以让himaker成为一种方法
himaker: name
^[:n | n timesRepeat: [Transcript show: 'Hi, ', name, '!']]