我有一个很长的实例变量列表要为我想要生成代码的类创建,而不是手工完成。该列表来自现有的SQL数据库。我的目的是首先使用Smalltalk以纯面向对象的方式完成所有操作,并且在我了解更多信息的同时,将数据保存回数据库并直接使用它。
有没有办法将名称列表传递给将生成它们的方法并将它们添加到类定义中?
实际上有一种在Smalltalk中动态添加或修改类定义的方法吗?我怀疑必须有,我想知道最佳实践方法。
更新:我想到的更像是将实例变量列表传递给将自动创建它们的方法。
更像是:
addVariablesAndAccessors className: MyClass variablesList: ('aaaa', 'bbbb', 'cccc')
然后会调用
AddVariables className: MyClass variableList: ('aaaa' 'bbbb' cccc')
和
generateAccessors className: MyClass variableList: ('aaaa' 'bbbb' cccc')
答案 0 :(得分:8)
在加载了重构工具的OmniBrowser中,选择类并在上下文菜单中 Refactor class>存取
或者,如果您只想为单个变量创建一个访问器,请选择 Refactor instance / class variable>访问者,并选择您要访问的变量。
答案 1 :(得分:4)
在Squeak中,你有Behavior>>addInstVarName: aString
,所以你可以这样做:
String addInstVarName: 'foo'
Squeak还具有重构支持以自动生成访问器。您既可以直接使用它,也可以查看AbstractInstanceVariableRefactoring>>createAccessors
以获得有关如何实现自己的灵感; - )
另一个相当hacky但不那么罕见的解决方案是只生成实例变量,但是不会添加访问器,而是覆盖doesNotUnderstand:
,当未定义的选择器发送到您的对象时会调用它。在那里,您可以检查是否有根据消息命名的实例变量,如果是这种情况,则返回/更改它。否则你只需super doesNotUnderstand: aMessage
。
关于你的评论:类也是对象,因此你不必做任何特殊的事情来将它们用作参数。你添加它的课程完全取决于你,并不重要。因此,添加实例变量的方法可能如下所示:
addVariablesNamed: aCollection on: aClass
aCollection do: [:each | aClass addInstVarName: each]
你可以这样称呼它:
yourObject addVariablesNamed: #('foo' 'bar' 'baz') on: ClassX
您可以在类CreateAccessorsForVariableRefactoring
答案 2 :(得分:2)
在Squeak中,在课程上打开Browser
。如果您“右键单击”(我永远不会记住按钮颜色)类列表中的类名,您将获得标准上下文菜单 - “浏览完整(b)”,依此类推。选择“更多...”,您将看到“创建inst var访问器”。选择它,您将获得实例变量的基本getter和setter。