<div dir="ltr">Hi Levente,<div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 20, 2018 at 2:38 PM, Levente Uzonyi <span dir="ltr"><<a href="mailto:leves@caesar.elte.hu" target="_blank">leves@caesar.elte.hu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Tue, 20 Mar 2018, Eliot Miranda wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi Jacob,<br>
On Tue, Mar 20, 2018 at 9:06 AM, Jakob Reschke <<a href="mailto:forums.jakob@resfarm.de" target="_blank">forums.jakob@resfarm.de</a>> wrote:<br>
      Hi Eliot,<br>
<br>
      ok, from your answers, it should access the declarations, not the<br>
      bindings of an environment.<br>
<br>
      With your requirement, that could be:<br>
         (self select: [:each | each isBehavior and: [each superclass isNil<br>
      and: [each environment == self "not misplaced via at:put:"]]]) asSet<br>
      asArray<br>
<br>
<br>
I don't understand "each environment == self".  A comment as to how this works would be good.  Further, is it not possible to declare a variable whose value is a root class?<br>
</blockquote>
<br></span>
With Environments came a new class hierarchy to replace Associations<br>
holding bindings: Binding and its subclasses: Alias, ClassBinding and<br>
Global.<br></blockquote><div><br></div><div>Thanks.  Now I get it.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
A class's binding is always a ClassBinding, a global variable's binding is<br>
always a Global, even if it points to a class. Alias wraps another binding and gives it a different name.<br>
So, it is fairly easy to detect if a binding is a class, a variable or a<br>
"renamed" class or variable.<br>
This also means that having an Association in an environment is a bug: an<br>
Association is not a Binding.<br>
So, the following should only ever return classes declared in the<br>
environment:<br>
<br>
        | roots |<br>
        roots := IdentitySet new.<br>
        declarations associationsDo: [ :binding |<br>
                binding class == ClassBinding ifTrue: [<br>
                        | class |<br>
                        (class := binding value) superclass ifNil: [<br>
                                roots add: class ] ] ].<br>
        ^roots asArray<br></blockquote><div><br></div><div>OK, but a bit hacky.  As you point out below...</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Another way to write it (though it uses a less up-to-date mechanism) if you're only interested in Classes (and not other kinds of Behavior):<br>
<br>
        | roots |<br>
        roots := IdentitySet new.<br>
        self allClassesDo: [ :class |<br>
                class superclass ifNil: [ roots add: class ] ].<br>
        ^roots asArray</blockquote><div><br></div><div>Ah, lovely.  This is the right way to write it.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
      I removed the #value sends because select: only iterates over the<br>
      values of a dictionary(-like object).<br>
<br>
<br>
Good point.<br>
 <br>
      I do not like the dependency on<br>
      the names of things, but that could also be an overreaction as the<br>
      result of my endeavor to make the tools work across environments. ;-)<br>
<br>
<br>
However it works the issue is avoiding duplicates caused by defining variables whose values are classes.  I used #name as that's the hammer I know.  I hope there's a better way :-)  Further, I hope you'll<br>
find it :-)<br>
</blockquote>
<br></span>
See above.<span class="HOEnZb"><font color="#888888"><br>
<br>
Levente</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 <br>
<br>
      Kind regards,<br>
      Jakob<br>
<br>
<br>
      2018-03-18 17:02 GMT+01:00 Eliot Miranda <<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>>:<br>
      > Hi Jacob,<br>
      ><br>
      >> On Mar 18, 2018, at 3:40 AM, Jakob Reschke <<a href="mailto:forums.jakob@resfarm.de" target="_blank">forums.jakob@resfarm.de</a>> wrote:<br>
      >><br>
      >> Hi Eliot,<br>
      >><br>
      >> Note that self bindings select: is not the same as self select: for an<br>
      >> Environment, as the latter only enumerates the declarations (its "own"<br>
      >> bindings).<br>
      >><br>
      >> Seems like the only sender is Class rootsOfTheWorld, which itself is<br>
      >> unsent. In that case, the Smalltalk "root" environment is hard-coded<br>
      >> and the specifics of bindings vs. declarations do not really matter.<br>
      >> But what should #rootClasses answer for other, possibly isolated<br>
      >> environments? What does the sender want to know?<br>
      >> - For an empty environment (no classes contained), should it answer an<br>
      >> empty collection?<br>
      ><br>
      > Yes<br>
      ><br>
      >> - Should the answer change if the "root" environment is imported?<br>
      ><br>
      > No<br>
      ><br>
      >> - For an environment that a) does not contain ProtoObject or Object,<br>
      >> but other classes deriving from them, and b) does not import the<br>
      >> "root" environment, should it answer an empty collection,<br>
      >> {ProtoObject} (although it is not imported) via superclass relations,<br>
      >> or something else?<br>
      ><br>
      > Empty<br>
      ><br>
      >> - Should the answer change if the "root" environment is imported?<br>
      >><br>
      >> By the way, would it work to have a second (different) ProtoObject<br>
      >> class in the image (in a different environment or under a different<br>
      >> name)?<br>
      ><br>
      > It should, right?<br>
      ><br>
      > the rootsOfTheWorld are easy to understand and hence to extend to environments.  Pre environments theRootsOfTheWorld are the classes that have no superclass (have nil as their superclass). <br>
      theRootsOfTheWorld is a set (has no duplicates) but can be a sequence.  Hence, given that Smalltalk can contain user defined variables, and the values of these variables can be anything, including<br>
      classes, the computation of theRootsOfTheWorld should filter out variables that just happen to refer to root classes to ensure that a set is answered.<br>
      ><br>
      > Extending this to environments then is straight forward.  theRootsOfTheWorld in an environment is a set of the classes defined in that environment that have no superclass. The computation should<br>
      not be confusable by variables whose values just happen to be toot classes.<br>
      ><br>
      > Now, given that theRootsOfTheWorld are used as the roots of code search (allImplementosOf: et al) the notion of a pet-environment theRootsOfTheWorld is suspect, given that code search should be<br>
      able to search all code.  But let's at least get the per-environment definition correct before we try and define a system-wide one.<br>
      ><br>
      >><br>
      >> Best regards,<br>
      >> Jakob<br>
      >><br>
      >> 2018-03-18 9:18 GMT+01:00 Eliot Miranda <<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>>:<br>
      >>> Hi David,<br>
      >>><br>
      >>>>> On Mar 17, 2018, at 8:19 PM, David T. Lewis <<a href="mailto:lewis@mail.msen.com" target="_blank">lewis@mail.msen.com</a>> wrote:<br>
      >>>>><br>
      >>>>> On Sat, Mar 17, 2018 at 04:54:36PM -0700, Eliot Miranda wrote:<br>
      >>>>> Hi David,<br>
      >>>>><br>
      >>>>>> On Sat, Mar 17, 2018 at 12:10 PM, <<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>> wrote:<br>
      >>>>>><br>
      >>>>>> David T. Lewis uploaded a new version of Environments to project The Trunk:<br>
      >>>>>> <a href="http://source.squeak.org/trunk/Environments-dtl.72.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/trunk<wbr>/Environments-dtl.72.mcz</a><br>
      >>>>>><br>
      >>>>>> ==================== Summary ====================<br>
      >>>>>><br>
      >>>>>> Name: Environments-dtl.72<br>
      >>>>>> Author: dtl<br>
      >>>>>> Time: 17 March 2018, 3:09:49.564301 pm<br>
      >>>>>> UUID: e9aed004-8798-41c0-83f9-a04f59<wbr>63dd55<br>
      >>>>>> Ancestors: Environments-jr.71, Environments-fbs.27<br>
      >>>>>><br>
      >>>>>> Merge Environments-fbs.27<br>
      >>>>>><br>
      >>>>>> =============== Diff against Environments-jr.71 ===============<br>
      >>>>>><br>
      >>>>>> Item was added:<br>
      >>>>>> + ----- Method: Environment>>rootClasses (in category 'accessing') -----<br>
      >>>>>> + rootClasses<br>
      >>>>>> +       "return a collection of classes which have a nil superclass"<br>
      >>>>>> +       ^ (self select: [:each | each isBehavior and: [each superclass<br>
      >>>>>> isNil]]) asOrderedCollection.!<br>
      >>>>>><br>
      >>>>><br>
      >>>>> At least for me this isn't quite good enough.  There's a possibility that<br>
      >>>>> someone could establish a variable whose value is a root, e.g. by<br>
      >>>>><br>
      >>>>> Smalltalk at: #MyRootClass put: ProtoObject<br>
      >>>>><br>
      >>>>> and that would cause rootClasses to answer a duplicate.  So IMO it needs to<br>
      >>>>> do one of<br>
      >>>>> - convert to a set and then back to a collection<br>
      >>>>> - answer a set<br>
      >>>>> - enumerate over associations, selecting those classes whose key is the<br>
      >>>>> same as their name<br>
      >>>>><br>
      >>>>> _,,,^..^,,,_<br>
      >>>>> best, Eliot<br>
      >>>><br>
      >>>> Hi Eliot,<br>
      >>>><br>
      >>>> Do you mean this?<br>
      >>>><br>
      >>>> Environment>>rootClasses<br>
      >>>>   "return a collection of classes which have a nil superclass"<br>
      >>>>   ^ (self select: [:each | each isBehavior and: [each superclass isNil]]) asSet asOrderedCollection.<br>
      >>><br>
      >>> That'll do but perhaps better is<br>
      >>><br>
      >>>          self bindings select: [:each | each value isBehavior and: [each value superclass isNil and: [each value name == each key]]]) collect:  [:each | each value]<br>
      >>><br>
      >>>><br>
      >>>><br>
      >>>> Note, I am not the author here, just tending to the inbox :-)<br>
      >>>><br>
      >>>> Thanks,<br>
      >>>> Dave<br>
      >>>><br>
      >>>><br>
      >>><br>
      >><br>
      ><br>
<br>
<br>
<br>
<br>
--<br>
_,,,^..^,,,_<br>
best, Eliot<br>
<br>
</blockquote>
</div></div><br><br>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>