简体   繁体   中英

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> ? (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.

Pharo

Go over all the classes and then from each class select all methods that match your needs (or use the Finder tool).

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

GNU Smalltalk

GST doesn't have as nice API, but it can be done also.

(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

(also Pharo and Squeak, and with ifNotNil: also GNU Smalltalk)

VW doesn't have #flatten , so it's implemented explicitly. For case-insensitive search #findSameAs:startingAt:wildcard: can also be used.

(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.

This may not work on all smalltalk dialects, but it works at least with squeak and pharo (other smalltalks may have similar tools/classes)

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.

Be aware that in some dialects (eg, Dolphin) the message #withAllSubclasses will only collect classes, and not metaclasses. Because of that the enumerations in @Peter's answer should add all metaclasses in an explicit way.

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.

Another difference with my code is that it iterates over the selectors of a class rather than over its methods.

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 #, .

We could have done instead:

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

etc. (note the use of #yourself )

This is to add different flavor to the list above.

<\/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>"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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