squeak(smalltalk)如何获取对象的所有方法(也包括继承的方法)

squeak(smalltalk)如何获取对象的所有方法(也包括继承的方法),smalltalk,squeak,Smalltalk,Squeak,如何获得对象可以理解的所有方法的列表 例如: set := 8 getAllMethods 将给我8在集合中能理解的所有方法。这很有趣,因为有以下几点。乍一看,人们可能会想一个这样的表达。 anObject class withAllSuperclasses gather: [:class | class methodDictionary] 它收集类及其超类中实现的所有方法。然而,如果一个方法是在一个类和它的一个超类中定义的,我们应该忽略后者,因为一个对象将使用类中的方法 为了弥补上述脚

如何获得对象可以理解的所有方法的列表

例如:

set := 8 getAllMethods

将给我8在集合中能理解的所有方法。这很有趣,因为有以下几点。乍一看,人们可能会想一个这样的表达。
  anObject class withAllSuperclasses gather: [:class | class methodDictionary]
它收集类及其超类中实现的所有方法。然而,如果一个方法是在一个类和它的一个超类中定义的,我们应该忽略后者,因为一个对象将使用类中的方法

为了弥补上述脚本的这一副作用,我们只需要收集在类中定义的方法,该类更接近对象类。一种方法是从上到下枚举类,将它们的所有方法添加到字典中。由于字典将只保留添加到给定键的最后一个元素(在本例中为选择器),因此只有属于某个对象协议的元素将保留:

methods := Dictionary new.
anObject class withAllSuperclasses reverseDo: [:class |
  methods addAll: class methodDictionary associations].
注意reverseDo:用于向下枚举类

另一种方法是自下而上枚举类,检查选择器是否已被访问:

methods := Dictionary new.
anObject class withAllSuperclasses do: [:class |
  class methodDictionary do: [:cm |
    methods at: cm selector ifAbsentPut: [cm]]]
cm代表编译方法吗

第二个版本稍长,更复杂,它有两个循环,一个嵌套在另一个循环中,需要条件逻辑:ifAbsentPut:。换句话说,它不应该被选中

在寻找创建集合的方法(在本例中为对象理解的所有方法的集合)时,首先确保确实需要这样的集合。例如,如果要在屏幕上显示该集合,则需要该集合。但是,如果您只打算将集合用于成员身份检查,那么可能还有其他方法可以继续。在您的情况下,您可以简单地询问对象:

anObject respondsTo: <selector>

这既简单又高效,因为它不创建集合等。

这很有趣,因为有以下几点。乍一看,人们可能会想一个这样的表达。
  anObject class withAllSuperclasses gather: [:class | class methodDictionary]
它收集类及其超类中实现的所有方法。然而,如果一个方法是在一个类和它的一个超类中定义的,我们应该忽略后者,因为一个对象将使用类中的方法

为了弥补上述脚本的这一副作用,我们只需要收集在类中定义的方法,该类更接近对象类。一种方法是从上到下枚举类,将它们的所有方法添加到字典中。由于字典将只保留添加到给定键的最后一个元素(在本例中为选择器),因此只有属于某个对象协议的元素将保留:

methods := Dictionary new.
anObject class withAllSuperclasses reverseDo: [:class |
  methods addAll: class methodDictionary associations].
注意reverseDo:用于向下枚举类

另一种方法是自下而上枚举类,检查选择器是否已被访问:

methods := Dictionary new.
anObject class withAllSuperclasses do: [:class |
  class methodDictionary do: [:cm |
    methods at: cm selector ifAbsentPut: [cm]]]
cm代表编译方法吗

第二个版本稍长,更复杂,它有两个循环,一个嵌套在另一个循环中,需要条件逻辑:ifAbsentPut:。换句话说,它不应该被选中

在寻找创建集合的方法(在本例中为对象理解的所有方法的集合)时,首先确保确实需要这样的集合。例如,如果要在屏幕上显示该集合,则需要该集合。但是,如果您只打算将集合用于成员身份检查,那么可能还有其他方法可以继续。在您的情况下,您可以简单地询问对象:

anObject respondsTo: <selector>
这既简单又高效,因为它不创建集合等。

在代码中,您可以使用所有选择器:

为您提供一组消息a的所有名称。KA.8可以理解的选择器

如果需要CompiledMethods,而不仅仅是消息名称,可以使用lookupSelector:

如果您不想在代码中这样做,而是想在IDE中找出对象可以理解的消息,那么我建议使用协议浏览器a。KA.词典工具。您可以通过浏览协议从类的上下文菜单打开它:

我使用它来查找AllSelector和lookupSelector:,它们是从行为继承的,而不是在类本身中定义的

在代码中,您可以使用所有选择器:

为您提供一组消息a的所有名称。KA.8可以理解的选择器

如果需要CompiledMethods,而不仅仅是消息名称,可以使用lookupSelector:

如果您不想在代码中这样做,而是想在IDE中找出对象可以理解的消息,那么我建议使用协议浏览器a。KA.词典工具。您可以通过浏览协议从类的上下文菜单打开它:

我使用它来查找AllSelector和lookupSelector:,它们是从行为继承的,而不是在类本身中定义的

原因是什么 AllSelector和lookupSelector:未在类中定义,但在行为中定义是因为类未对元类建模,而元类也有要反映的协议。之所以所有Selector和lookupSelector:未在类中定义,但在行为中定义,是因为类未对元类建模,元类也有要反映的协议。