searching for Classes defining inst/class var named

79 views
Skip to first unread message

Joachim Tuchel

unread,
May 17, 2019, 5:11:43 AM5/17/19
to VA Smalltalk
I just stumbled across something that left me stunned: I wanted to search for Class(es) that define an instance variable named #fileContents

I knew there is such a Class and it is loaded in the image. And I know that class is neither implementing a getter nor setter for this variable.
But I found no way to search for it.

I tried "References" but that only finds another implementor of a method named #fileContents.

I can hardly believe I never had this problem before, and I also can hardly believe there is no way to find Classes defining a variable by the variable's name. Or am I missing something here? I looked all that's available in my Transcript's Tools Menu - and found... nothing! In the Query submenu there is "Classes Using Pool...", but nothing that allows me to search vor variable names... The only thing that comes close is VA Assist's "Browse Methods Including String..." but it is a bit slow...

Strange, isn't it? *scratching head*


Joachim


Seth Berman

unread,
May 17, 2019, 11:45:13 AM5/17/19
to VA Smalltalk
Hi Joachim,

It seems like you answered your own question when you stated "I can hardly believe I never had this problem before".
I don't think your alone in this, because I don't think its a very common query.  Or if it is, I can't recall the last time I needed
to locate, from a global scope, a class on the basis of a property name...be it a instVar, classVar or classInstVar.

I'm not saying its never happened...and each to their own style of thinking of course, but it just doesn't seem like a very common query to me
and therefore not something we've been asked to add to the menus.
It seems reasonable that not every combination of query Object meta-state is going to be captured in menu items.
If we go down this route...I think the better solution is to have a more generic query construction capability that allows for querying
any combination of state such as instVar, classVar, classInstVar names or counts, shape (i.e. bytes, words, longs, pointer), byte size and so forth ....
There's lots of others that I could come up with.

But, in the interest of being helpful, I provide the following which I hope will get you the information you need.

| result findMe instVarQuery classVarQuery classInstVarQuery query |

findMe := 'instVar'.

"Place your selected query block in the 'query' var"
instVarQuery := [:cls | (cls allInstVarNames indexOf: findMe) > 0].
classVarQuery := [:cls | cls classPool includesKey: findMe].
classInstVarQuery := [:cls | instVarQuery value: cls class].
query := instVarQuery.

result := System classHierarchyRoots
inject: OrderedCollection new
into: [:col :root | root withAllSubclassesDo: [:cls | (query value: cls) ifTrue: [col add: cls asClass]]. col].
result inspect

- Seth

Richard Sargent

unread,
May 17, 2019, 1:20:03 PM5/17/19
to VA Smalltalk
On Friday, May 17, 2019 at 8:45:13 AM UTC-7, Seth Berman wrote:
Hi Joachim,

It seems like you answered your own question when you stated "I can hardly believe I never had this problem before".
I don't think your alone in this, because I don't think its a very common query.  Or if it is, I can't recall the last time I needed
to locate, from a global scope, a class on the basis of a property name...be it a instVar, classVar or classInstVar.

I'm not saying its never happened...and each to their own style of thinking of course, but it just doesn't seem like a very common query to me
and therefore not something we've been asked to add to the menus.
It seems reasonable that not every combination of query Object meta-state is going to be captured in menu items.
If we go down this route...I think the better solution is to have a more generic query construction capability that allows for querying
any combination of state such as instVar, classVar, classInstVar names or counts, shape (i.e. bytes, words, longs, pointer), byte size and so forth ....
There's lots of others that I could come up with.

But, in the interest of being helpful, I provide the following which I hope will get you the information you need.

| result findMe instVarQuery classVarQuery classInstVarQuery query |

findMe := 'instVar'.

"Place your selected query block in the 'query' var"
instVarQuery := [:cls | (cls allInstVarNames indexOf: findMe) > 0].
classVarQuery := [:cls | cls classPool includesKey: findMe].
classInstVarQuery := [:cls | instVarQuery value: cls class].
query := instVarQuery.

result := System classHierarchyRoots
inject: OrderedCollection new
into: [:col :root | root withAllSubclassesDo: [:cls | (query value: cls) ifTrue: [col add: cls asClass]]. col].
result inspect


We can forget just how easily Smalltalk code can be searched! 

But, I wouldn't use #allInstVarNames, since that will also give you the subclasses of the one which declared the instance variable.

Seth Berman

unread,
May 17, 2019, 1:39:20 PM5/17/19
to VA Smalltalk
Nice catch!


| result findMe instVarQuery classVarQuery classInstVarQuery query |

findMe := 'elements'.

"Place your selected query block in the 'query' var"
instVarQuery := [:cls | (cls instVarNames indexOf: findMe) > 0].
classVarQuery := [:cls | cls classPool includesKey: findMe].
classInstVarQuery := [:cls | instVarQuery value: cls class].
query := instVarQuery.

result := System classHierarchyRoots
inject: OrderedCollection new
into: [:col :root | root withAllSubclassesDo: [:cls | (query value: cls) ifTrue: [col add: cls asClass]]. col].
result inspect

Joachim Tuchel

unread,
May 18, 2019, 1:11:50 AM5/18/19
to VA Smalltalk
HI Seth,

first of all, thanks for your code example. Works well and is much faster than "Methods including text".

I agree this is not a common search. And the menus in VAST are presenting a vast selection of options, so I fully agree we don't want or need another battery of search options in the menus.
My comment was not so much a complaint about a missing feature. I mostly wanted to share my surprise about the fact I almost never needed it before (or maybe did, but can't remember) and that here really is no way to do it (unless with a code snippet) although Smalltalk allows for such queries easily - as you just proved with your code.

Your code is a nice prototype for a system-wide, multi-purpose search field ;-)

Again, thanks a lot!

Mariano Martinez Peck

unread,
May 20, 2019, 11:40:42 AM5/20/19
to VA Smalltalk
On Sat, May 18, 2019 at 2:11 AM Joachim Tuchel <jtu...@objektfabrik.de> wrote:
HI Seth,

first of all, thanks for your code example. Works well and is much faster than "Methods including text".

I agree this is not a common search. And the menus in VAST are presenting a vast selection of options, so I fully agree we don't want or need another battery of search options in the menus.
My comment was not so much a complaint about a missing feature. I mostly wanted to share my surprise about the fact I almost never needed it before (or maybe did, but can't remember) and that here really is no way to do it (unless with a code snippet) although Smalltalk allows for such queries easily - as you just proved with your code.

Your code is a nice prototype for a system-wide, multi-purpose search field ;-)

Again, thanks a lot!



So, you have the material for your next blog post? 

:)


--
Mariano Martinez Peck
Software Engineer, Instantiations Inc.

Joachim Tuchel

unread,
May 21, 2019, 2:54:04 AM5/21/19
to VA Smalltalk
Oh, you mean the one for last week... ?


;-)

Peter Ode

unread,
May 27, 2019, 4:29:25 PM5/27/19
to va-sma...@googlegroups.com
I read your code search posts with interest. 
I have been trying to find methods with #aSymbol
without success.

The code provided for your snippet search does not work for this purpose.

Are there other ways to search an entire image for specific source code text?
Specifically, I need to find certain symbols?

Thank you.

Peter



Seth Berman

unread,
May 27, 2019, 4:37:53 PM5/27/19
to VA Smalltalk
Hi Peter,

To find a symbol literal, you should be able to use the "Browse References" menu item
Transcript -> Tools -> Browse References...

You can do more exhaustive regex searches using VA Assist "Find String"
Class Browser Menu -> Classes -> VA Assist Pro Tools -> Find String -> In System...
then type a pattern.

Is this what you are looking for?

- Seth

Peter Ode

unread,
May 27, 2019, 4:51:44 PM5/27/19
to va-sma...@googlegroups.com
Hi Seth,

Thank you for the suggestions.
I'm using an older version of VAST so don't have VA Assist Pro Tools and Browse References does not return anything.

I've installed Class Text Finder (by Runar Jordahl) but that doesn't help for finding symbols.

Any suggestions?
Thank you.

Peter




--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to va-smalltalk...@googlegroups.com.
To post to this group, send email to va-sma...@googlegroups.com.
Visit this group at https://groups.google.com/group/va-smalltalk.
To view this discussion on the web visit https://groups.google.com/d/msgid/va-smalltalk/9d9cdc84-dd38-4f4d-9f8a-316631b73027%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Seth Berman

unread,
May 27, 2019, 5:03:44 PM5/27/19
to VA Smalltalk
Hi Peter,

Perhaps the following?
| result findMe query |

findMe := #aSymbol.

"Place your selected query block in the 'query' var"
symbolLiteralQuery := [:cm | cm allLiterals anySatisfy: [:lit | lit == findMe]].
query := symbolLiteralQuery.

result := System classHierarchyRoots
inject: OrderedCollection new
into: [:col :root | root withAllSubclassesDo: [:cls | 
cls methodsDo: [:m | 
(query value: m) ifTrue: [col add: m]]]. col].
result inspect
To unsubscribe from this group and stop receiving emails from it, send an email to va-smalltalk+unsubscribe@googlegroups.com.

Peter Ode

unread,
May 27, 2019, 5:14:56 PM5/27/19
to va-sma...@googlegroups.com
Hi Seth,

Thank you. The code you provided did find many symbols after I did a minor fix (added symbolLiteralQuery to the variables declarations in the 1st line) as follows:

| result findMe query symbolLiteralQuery |


findMe := #aSymbol.

"Place your selected query block in the 'query' var"
symbolLiteralQuery := [:cm | cm allLiterals anySatisfy: [:lit | lit == findMe]].
query := symbolLiteralQuery.

result := System classHierarchyRoots
inject: OrderedCollection new
into: [:col :root | root withAllSubclassesDo: [:cls |
cls methodsDo: [:m |
(query value: m) ifTrue: [col add: m]]]. col].
result inspect.

Although the above worked for many symbols, there are some specific symbols that it does not find.
Therefore, I'm still trying to find certain methods based on #aSymbol.

Peter



To unsubscribe from this group and stop receiving emails from it, send an email to va-smalltalk...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to va-smalltalk...@googlegroups.com.

To post to this group, send email to va-sma...@googlegroups.com.
Visit this group at https://groups.google.com/group/va-smalltalk.

Seth Berman

unread,
May 27, 2019, 5:20:39 PM5/27/19
to VA Smalltalk
Hi Peter,

Can you give me an example?  If so, I can probably expand it, but I don't know what this might refer to.
The code I provided assumes that this code that has been loaded into the image.
Traversing an envy repository (including code not in your local image) was not provided.

- Seth
To unsubscribe from this group and stop receiving emails from it, send an email to va-smalltalk+unsubscribe@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to va-smalltalk+unsubscribe@googlegroups.com.

Peter Ode

unread,
May 27, 2019, 6:13:11 PM5/27/19
to va-sma...@googlegroups.com
Hi Seth,

Thanks again. Here's an example for our VA Smalltalk based eCommerce system. 
We have developed a template system for dynamic web pages, static pages and email messages. Below is a snipped from an email message template that includes #theSymbols I'm looking for.

<#include _order_top.txt>
*** <#atWebLabel> Confirmation # <#atId> ***

You should retain a copy of this Order Confirmation for your records.

Dear <#atProfileEntityFullNameStartingWithFirstName>,

Thank you for your Internet Order.
...

Using your "findMe" code snippet, I'm able to find #atId and #atWebLabel but 
can't find: #atProfileEntityFullNameStartingWithFirstName

This is a production system that I've inherited (in terms of support) and need to make some changes to the code. 
The image must have the code loaded somewhere that contains: #atProfileEntityFullNameStartingWithFirstName

Many thanks.

Peter

To unsubscribe from this group and stop receiving emails from it, send an email to va-smalltalk...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to va-smalltalk...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to va-smalltalk...@googlegroups.com.

To post to this group, send email to va-sma...@googlegroups.com.
Visit this group at https://groups.google.com/group/va-smalltalk.

Seth Berman

unread,
May 27, 2019, 6:57:31 PM5/27/19
to VA Smalltalk
Hi Peter,

Ok, so those look like symbols in that they have a leading #, but I'm guessing they are not literal symbols (as in instances of the Symbol class)...at least not at compile time.
So, it seems like what you really need is just source text search?
How is this template stored?  Is it stored as just a String in a method...or is there something else going on.
In the meantime, I can just put together a simple string search for your purposes.
See if this one gets what you need.

| result findMe query symbolLiteralQuery strTemplateQuery |

findMe := #aSymbol.

symbolLiteralQuery := [:cm | cm allLiterals anySatisfy: [:lit | lit == findMe]].
strTemplateQuery := [:cm | | stream findStr done found  |
stream := cm sourceString readStream.
findStr := findMe asString.
done := stream atEnd.
found := false.
[done] whileFalse: [
((stream skipTo: $#) 
and: [((stream contents size - stream position) >= findMe size)
and: [(stream next: findMe size) = findStr]])
ifTrue: [done := found := true] ifFalse: [done := stream atEnd]]. found].

result := System classHierarchyRoots
inject: Set new
into: [:col :root | root withAllSubclassesDo: [:cls | 
cls methodsDo: [:m |  ((symbolLiteralQuery value: m) or: [strTemplateQuery value: m]) ifTrue: [col add: m]]]. col].
result asOrderedCollection inspect.

- Seth
To unsubscribe from this group and stop receiving emails from it, send an email to va-smalltalk+unsubscribe@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to va-smalltalk+unsubscribe@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to va-smalltalk+unsubscribe@googlegroups.com.

Peter Ode

unread,
May 27, 2019, 7:32:13 PM5/27/19
to va-sma...@googlegroups.com
Hi Seth,

The templates are stored as text files on disk. For example: order.txt

But, I do not need to search the templates.

I only need to search for methods in the image that process the "tags" that look like symbols.
You are correct, #atProfileEntityFullNameStartingWithFirstName may not be a real #symbol.

I'm now checking the last code snippet you provided. Thanks.

Peter



To unsubscribe from this group and stop receiving emails from it, send an email to va-smalltalk...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to va-smalltalk...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to va-smalltalk...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to va-smalltalk...@googlegroups.com.

To post to this group, send email to va-sma...@googlegroups.com.
Visit this group at https://groups.google.com/group/va-smalltalk.
Reply all
Reply to author
Forward
0 new messages