[comp.lang.smalltalk] browsing by partial method name.

FUCHS@pucc.Princeton.EDU (Ira Fuchs) (05/27/88)

Can someone answer this (novice) question: I would like to open a browser for
all methods whose selector contains a specified string (e.g. 'Sensor'). I
assume that the way to do this is to use browseAllSelections: and to provide
a block that evaluates to true when the selector meets this criteria, but
can someone tell me what this block should be? Thanks for any help.

susser@Apple.COM (Joshua Susser) (06/01/88)

In article <5376@pucc.Princeton.EDU> FUCHS@pucc.Princeton.EDU writes:
>Can someone answer this (novice) question: I would like to open a browser for
>all methods whose selector contains a specified string (e.g. 'Sensor'). I
>assume that the way to do this is to use browseAllSelections: and to provide
>a block that evaluates to true when the selector meets this criteria, but
>can someone tell me what this block should be? Thanks for any help.

I don't have browseAllSelections: in my image, but I'm working in LV1, so
that's not too strange.  If that method is anything like the
browseAllSelect: method in LV1, it won't help you, as it only has access to
the CompiledMethod object, and doesn't know about the selectors.

So here's my quick and dirty solution to your problem. You have to add
two messages to the system, but that's what Smalltalk's all about.

Joshua Susser
Object Engineer
susser@apple.com
{sun,nsc,amdahl,decwrl}!apple!susser

---------- cut here ----------
!SystemDictionary methodsFor: 'retrieving'!
allPartialImplementorsOf: aString  
    "Answer a SortedCollection of all the methods that implement a message 
    containing the substring aString."

    | aCollection match |
    aCollection _ SortedCollection new.
    match _ aString asLowercase.
    Cursor wait showWhile:
        [self allBehaviorsDo:
            [:class |
            class selectors do: [:selector |
                (selector asLowercase findString: match startingAt: 1) > 0
                    ifTrue: [aCollection add: class name, ' ', selector]]]].
    ^aCollection! !

!SystemDictionary methodsFor: 'browsing'!
browseAllPartialImplementorsOf: aString
    "Create and schedule a message browser on each method that implements 
    a message whose selector contains the argument, aString. For example, 
    Smalltalk browseAllPartialImplementorsOf: 'Float'."

    ^self browseMessageList: (self allPartialImplementorsOf: aString)
            name: 'Partial Implementors of ' , aString! !

nhj@cs.bham.ac.uk (Nick Jurascheck <JurascheckNH>) (06/07/88)

>>Can someone answer this (novice) question: I would like to open a 
>>browser for all methods whose selector contains a specified string 
>>(e.g. 'Sensor'). I assume that the way to do this is to use 
>>browseAllSelections: and to provide a block that evaluates to true 
>>when the selector meets this criteria, but can someone tell me what 
>>this block should be? Thanks for any help.

	The method browseAllSelect supplies a CompiledMethod variable
for the input parameter block, and this does not have the selector name
as one of its attributes. For this reason browseAllSelect does not
seem to be suitable for finding methods by name.

	My solution is to create a parallel search method
<browseAllSelectByName> which uses the selector name, rather than its
compiled method as the block argument. You can then use <match:>
(optionally with wildcards '*' and '#'), to locate methods containing
specified strings.

	First copy <allSelect:>, in class SystemDictionary to
<allSelectByName:>. The only alteration needed is to replace the line
:
		[:sel | (aBlock value: (class compiledMethodAt: sel))
with:
		[:sel | (aBlock value: sel).
	
	This causes the temporary variable of the top level input
block, which the user supplies, to be instantiated with the selector
name rather than the actual compiled method.

	The second step is simply to create a method which can be sent
to the global system variable <Smalltalk>, in the same way as
<browseAllSelect>, but which calls <allSelectByName:> instead of
<allSelect:>. This is just an appropriately edited copy of
<browseAllSelect>, which I called <browseAllSelectByName>.

	To use this new method type something like:
	
		Smalltalk browseAllSelectByName:
	[:methodName | 'Sens*'  match: methodName printString ].

	As a newcomer to SmallTalk myself, I can't promise that this
is the "best" way to achieve this result, but...... it works.

-- 
nick
INTERNET: JurascheckNH%cs.bham.ac.uk@cunyvm.cuny.edu
JANET: JurascheckNH@uk.ac.bham.cs UUCP: ...!mcvax!bhamcs!JurascheckNH
BITNET: JurascheckNH%cs.bham.ac.uk@ukacrl.bitnet