简体   繁体   English

"如何在 Smalltalk 中找到所有可用的方法并按名称搜索?"

[英]How to find all methods available in Smalltalk and search by name?

In Smalltalk, is there a way to search for all methods available (of any object), say, that contain the word convert<\/code> (case insensitive search), and also contain the word string<\/code> ?在 Smalltalk 中,有没有办法搜索(任何对象的)所有可用方法,比如包含单词convert<\/code> (不区分大小写的搜索),还包含单词string<\/code> ? (the method name, not the source code) (方法名,不是源代码)

"

In Smalltalk you have direct access to all classes, their methods and their source code, so you can go through them. 在Smalltalk中,您可以直接访问所有类,它们的方法和源代码,因此您可以浏览它们。

Pharo 菲罗

Go over all the classes and then from each class select all methods that match your needs (or use the Finder tool). 遍历所有类,然后从每个类中选择符合您需求的所有方法(或使用Finder工具)。

Object withAllSubclasses flatCollect: [ :cls |
    cls methods select: [ :method |
        (method selector includesSubstring: 'convert' caseSensitive: false) and: [
        (method selector includesSubstring: 'string' caseSensitive: false) ]
    ]
].

GNU Smalltalk GNU Smalltalk

GST doesn't have as nice API, but it can be done also. GST没有那么好的API,但它也可以做到。

(Object withAllSubclasses collect: [ :cls |
    cls methodDictionary ifNotNil: [ :dict |
        dict values select: [ :method |
            (method selector asLowercase indexOfSubCollection: 'convert' asLowercase) > 0 and: [
            (method selector asLowercase indexOfSubCollection: 'string' asLowercase) > 0 ]
        ]
    ]
]) join

VisualWorks VisualWorks中

(also Pharo and Squeak, and with ifNotNil: also GNU Smalltalk) (也是Pharo和Squeak,还有ifNotNil:还有GNU Smalltalk)

VW doesn't have #flatten , so it's implemented explicitly. 大众没有#flatten ,所以它是明确实现的。 For case-insensitive search #findSameAs:startingAt:wildcard: can also be used. 对于不区分大小写的搜索#findSameAs:startingAt:wildcard:也可以使用。

(Object withAllSubclasses collect: [ :cls |
    cls methodDictionary values select: [ :method |
        (method selector asLowercase findString: 'convert' asLowercase startingAt: 1) > 0 and: [
        (method selector asLowercase findString: 'string' asLowercase startingAt: 1) > 0 ]
    ]
]) inject: #() into: [ :arr :each | arr, each ]

Dolphin 海豚

Dolphin seems to have different object model, see Leandro's answer below. 海豚似乎有不同的对象模型,请参阅下面的Leandro的答案

This may not work on all smalltalk dialects, but it works at least with squeak and pharo (other smalltalks may have similar tools/classes) 这可能不适用于所有的smalltalk方言,但它至少适用于吱吱声和pharo(其他小方可能有类似的工具/类)

SystemNavigation default browseAllSelect:[:e |
(e selector includesSubstring:'convert' caseSensitive:false)
    and:[e selector includesSubstring:'string' caseSensitive:false]]

This is more a complement to the answer given by @Peter. 这更像是@Peter给出的答案的补充。

Be aware that in some dialects (eg, Dolphin) the message #withAllSubclasses will only collect classes, and not metaclasses. 请注意,在某些方言(例如,Dolphin)中,消息#withAllSubclasses将仅收集类,而不是元类。 Because of that the enumerations in @Peter's answer should add all metaclasses in an explicit way. 因此,@ Peter的答案中的枚举应该以明确的方式添加所有元类。

For instance, 例如,

selectors := OrderedCollection new.
Object withAllSubclasses do: [:class | | matching |
  matching := class selectors select: [:s |
    (s includesString: 'onvert') and: [s includesString: 'tring']].
  selectors addAll: matching.
  matching := class class selectors select: [:s |
    (s includesString: 'onvert') and: [s includesString: 'tring']].
  selectors addAll: matching].
^selectors

Note BTW that I've removed the first letter from both 'convert' and 'string' to cheaply prevent case mismatches. 请注意,我已经删除了'convert''string'的第一个字母,以便廉价地防止案例不匹配。

Another difference with my code is that it iterates over the selectors of a class rather than over its methods. 与我的代码的另一个区别是它迭代了类的selectors而不是它的方法。

UPDATE UPDATE

Note that I've used two enumerations because we cannot do this: 请注意,我使用了两个枚举,因为我们不能这样做:

class selectors , class class selectors select: [:s |

etc. The reason is that the selectors of a class come in a Set and these do not understand #, . 原因是一个classselectors进入一个Set ,这些不理解#,

We could have done instead: 我们本可以做到:

all := class selectors addAll: class class selectors; yourself.
all selectors select: [:s |

etc. (note the use of #yourself ) 等(注意使用#yourself

This is to add different flavor to the list above.这是为上面的列表添加不同的风味。

@Smalltalk\/X @Smalltalk\/X<\/h2>
 Object withAllSubclasses flatCollect: [ :cls | cls methodDictionary values select: [ :method | (method selector includesSubstring: 'convert' caseSensitive: false) and: [ (method selector includesSubstring: 'string' caseSensitive: false) ] ] ].<\/code><\/pre>"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM