我是Smalltalk的新来者,并在Squeak中学到了它。但我发现很多事情在Smalltalk中令人困惑。在吱吱声中,MetaClass
和MetaClass class
是彼此的阶级。如果我想创建对象MetaClass
,我应该向其new
类发送消息MetaClass class
。但它必须首先作为一个对象存在,才能接受这个消息。所以我必须首先创建对象MetaClass class
,这只能通过向尚未创建的对象new
发送消息MetaClass
来完成。所以这是一个鸡蛋或鸡蛋问题。
当然我现在可以在Squeak中创建对象,因为在打开Squeak时已经自动神奇地创建了MetaClass
和MetaClass class
个对象。但我不知道怎么做。也许它们是以某种方式创建而不是通过发送消息。但是它与Smalltalk的精神相矛盾:一切都是通过发送消息而发生的,除了几点(变量声明,赋值,返回和原语)。
上述推理有什么问题吗?提前谢谢。
答案 0 :(得分:12)
你的问题是双重的,让我们分开回答。
如何创建相互依赖的类?
你是对的,Metaclass
和Metaclass class
是Smalltalk类和元类的并行层次结构中的奇点。它们是如何创建的?
这取决于您使用的Smalltalk。对于GNU Smalltalk,我不确定,但对于原始Smalltalk-80(VisualWorks,VA aka VisualAge,SqueakPharo)的后代,它们是在Bootstrap过程中创建的,用于创建初始图像。
然而,至少对于Squeak来说,这个引导程序至少发生在15年前,如果不是更多的话。 Metaclass
及其班级甚至可能长达30年。
长话短说,两个类都是在典型的图像处理之外创建的,并且手动链接在一起。
但是如果对象已经存在多年,那么就会出现问题
Smalltalk创业公司会发生什么?
与面向对象的Ruby或Python等语言相反,Smalltalk不需要在每次启动时都使用Object
之类的东西创建基本对象环境。为什么呢?
当Smalltalk保存并关闭时,它基本上会获取其所有对象的快照,并将这些活动对象保存到文件中。当它再次启动时,它只需要从快照中读取对象并“恢复”它们。
因此,对于Metaclass
和Metaclass class
,两个对象都从快照中读取并恢复,从这一点开始,它们完全正常运行;它们不再需要手动创建。
答案 1 :(得分:11)
“自动创建”流程实际上称为bootstrapping。这就是鸡蛋问题得到解决的方法。一旦系统被引导,所有其余的都可以用系统本身表示。因此,与Smalltalk的理念并不矛盾,即所有事情都是通过发送消息而发生的,因为一旦它被引导,它就变成了一个Smalltalk系统。
答案 2 :(得分:8)
Metaclass class class = Metaclass
是奇怪循环的经典学术范例。但是如果你稍微询问一下,你可以在Smalltalk中找到很多其他人。
Object superclass superclass class superclass = Object
中的ProtoObject更长链)MethodDictionary methodDictionary class = MethodDictionary
)的实例中。ByteSymbol name class = ByteSymbol
中与ByteSymbol一起使用)。Array superclass subclasses class = Array
)的子类。(Smalltalk globals at: #Smalltalk) = Smalltalk
)。我让你自己继续列表。
无论实现什么,最终的问题是你是否可以设计一个像Smalltalk这样的自我描述系统而没有这些奇怪的循环,如果你遵循http://en.wikipedia.org/wiki/Kurt_G%C3%B6del#The_Incompleteness_Theorem的子链接,你可能会看到一个不那么正面的答案/ p>
与此类系统遇到的引导程序问题相关,一种有效的方法是克隆自己以改变自己,当您想要更改用于更改/描述类的基类时,在Smalltalk映像中尤其如此。
因此,我之前的简明回答通过应用规则的字母(https://stackoverflow.com/help/deleted-answers)而删除,而不是我认为的精神:
以下是解决方法: http://en.wikipedia.org/wiki/Drawing_Hands
最后一点,我宁愿阅读 Smalltalk的不可思议的一致性 ,但我绝对有偏见。