[squeak-dev] The Trunk: Environments-dtl.72.mcz
Jakob Reschke
forums.jakob at resfarm.de
Tue Mar 20 22:34:29 UTC 2018
Note that the following also results in ClassBinding:
Smalltalk globals at: #Foo put: ProtoObject.
(Smalltalk globals associationAt: #Foo) class
...so distinguishing globals that are classes from proper classes is
not that easy.
Environment>>allClassesAndTraitsDo: uses the same [key == value name]
condition that Eliot proposed earlier, so it is probably unjustified
that I avoid it. But note further that Environment>>allClassesDo: uses
#isKindOf: to separate classes from traits...
And for the [each environment == self] bit in my code snippet: each
class (and trait) "has" an environment. Since self in this case is the
environment to which #rootClasses was sent, the condition was intended
to filter out those behaviors that are not indigenous to the queried
environment, but bound there nevertheless (myEnv at: #Foo put:
ProtoObject). Additional globals for root classes would be filtered
out by asSet.
2018-03-20 22:49 GMT+01:00 Eliot Miranda <eliot.miranda at gmail.com>:
> Hi Levente,
>
> On Tue, Mar 20, 2018 at 2:38 PM, Levente Uzonyi <leves at caesar.elte.hu>
> wrote:
>>
>> On Tue, 20 Mar 2018, Eliot Miranda wrote:
>>
>>> Hi Jacob,
>>> On Tue, Mar 20, 2018 at 9:06 AM, Jakob Reschke <forums.jakob at resfarm.de>
>>> wrote:
>>> Hi Eliot,
>>>
>>> ok, from your answers, it should access the declarations, not the
>>> bindings of an environment.
>>>
>>> With your requirement, that could be:
>>> (self select: [:each | each isBehavior and: [each superclass
>>> isNil
>>> and: [each environment == self "not misplaced via at:put:"]]])
>>> asSet
>>> asArray
>>>
>>>
>>> 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?
>>
>>
>> With Environments came a new class hierarchy to replace Associations
>> holding bindings: Binding and its subclasses: Alias, ClassBinding and
>> Global.
>
>
> Thanks. Now I get it.
>
>>
>>
>> A class's binding is always a ClassBinding, a global variable's binding is
>> always a Global, even if it points to a class. Alias wraps another binding
>> and gives it a different name.
>> So, it is fairly easy to detect if a binding is a class, a variable or a
>> "renamed" class or variable.
>> This also means that having an Association in an environment is a bug: an
>> Association is not a Binding.
>> So, the following should only ever return classes declared in the
>> environment:
>>
>> | roots |
>> roots := IdentitySet new.
>> declarations associationsDo: [ :binding |
>> binding class == ClassBinding ifTrue: [
>> | class |
>> (class := binding value) superclass ifNil: [
>> roots add: class ] ] ].
>> ^roots asArray
>
>
> OK, but a bit hacky. As you point out below...
>
>>
>>
>> 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):
>>
>> | roots |
>> roots := IdentitySet new.
>> self allClassesDo: [ :class |
>> class superclass ifNil: [ roots add: class ] ].
>> ^roots asArray
>
>
> Ah, lovely. This is the right way to write it.
>
>>> I removed the #value sends because select: only iterates over the
>>> values of a dictionary(-like object).
>>>
>>>
>>> Good point.
>>>
>>> I do not like the dependency on
>>> the names of things, but that could also be an overreaction as the
>>> result of my endeavor to make the tools work across environments.
>>> ;-)
>>>
>>>
>>> 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
>>> find it :-)
>>
>>
>> See above.
>>
>> Levente
>>
>>
>>>
>>>
>>> Kind regards,
>>> Jakob
>>>
>>>
>>> 2018-03-18 17:02 GMT+01:00 Eliot Miranda <eliot.miranda at gmail.com>:
>>> > Hi Jacob,
>>> >
>>> >> On Mar 18, 2018, at 3:40 AM, Jakob Reschke
>>> <forums.jakob at resfarm.de> wrote:
>>> >>
>>> >> Hi Eliot,
>>> >>
>>> >> Note that self bindings select: is not the same as self select:
>>> for an
>>> >> Environment, as the latter only enumerates the declarations (its
>>> "own"
>>> >> bindings).
>>> >>
>>> >> Seems like the only sender is Class rootsOfTheWorld, which
>>> itself is
>>> >> unsent. In that case, the Smalltalk "root" environment is
>>> hard-coded
>>> >> and the specifics of bindings vs. declarations do not really
>>> matter.
>>> >> But what should #rootClasses answer for other, possibly isolated
>>> >> environments? What does the sender want to know?
>>> >> - For an empty environment (no classes contained), should it
>>> answer an
>>> >> empty collection?
>>> >
>>> > Yes
>>> >
>>> >> - Should the answer change if the "root" environment is
>>> imported?
>>> >
>>> > No
>>> >
>>> >> - For an environment that a) does not contain ProtoObject or
>>> Object,
>>> >> but other classes deriving from them, and b) does not import the
>>> >> "root" environment, should it answer an empty collection,
>>> >> {ProtoObject} (although it is not imported) via superclass
>>> relations,
>>> >> or something else?
>>> >
>>> > Empty
>>> >
>>> >> - Should the answer change if the "root" environment is
>>> imported?
>>> >>
>>> >> By the way, would it work to have a second (different)
>>> ProtoObject
>>> >> class in the image (in a different environment or under a
>>> different
>>> >> name)?
>>> >
>>> > It should, right?
>>> >
>>> > 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).
>>> 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
>>> classes, the computation of theRootsOfTheWorld should filter out
>>> variables that just happen to refer to root classes to ensure that a set is
>>> answered.
>>> >
>>> > 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
>>> not be confusable by variables whose values just happen to be toot
>>> classes.
>>> >
>>> > 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
>>> 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.
>>> >
>>> >>
>>> >> Best regards,
>>> >> Jakob
>>> >>
>>> >> 2018-03-18 9:18 GMT+01:00 Eliot Miranda
>>> <eliot.miranda at gmail.com>:
>>> >>> Hi David,
>>> >>>
>>> >>>>> On Mar 17, 2018, at 8:19 PM, David T. Lewis
>>> <lewis at mail.msen.com> wrote:
>>> >>>>>
>>> >>>>> On Sat, Mar 17, 2018 at 04:54:36PM -0700, Eliot Miranda
>>> wrote:
>>> >>>>> Hi David,
>>> >>>>>
>>> >>>>>> On Sat, Mar 17, 2018 at 12:10 PM,
>>> <commits at source.squeak.org> wrote:
>>> >>>>>>
>>> >>>>>> David T. Lewis uploaded a new version of Environments to
>>> project The Trunk:
>>> >>>>>> http://source.squeak.org/trunk/Environments-dtl.72.mcz
>>> >>>>>>
>>> >>>>>> ==================== Summary ====================
>>> >>>>>>
>>> >>>>>> Name: Environments-dtl.72
>>> >>>>>> Author: dtl
>>> >>>>>> Time: 17 March 2018, 3:09:49.564301 pm
>>> >>>>>> UUID: e9aed004-8798-41c0-83f9-a04f5963dd55
>>> >>>>>> Ancestors: Environments-jr.71, Environments-fbs.27
>>> >>>>>>
>>> >>>>>> Merge Environments-fbs.27
>>> >>>>>>
>>> >>>>>> =============== Diff against Environments-jr.71
>>> ===============
>>> >>>>>>
>>> >>>>>> Item was added:
>>> >>>>>> + ----- Method: Environment>>rootClasses (in category
>>> 'accessing') -----
>>> >>>>>> + rootClasses
>>> >>>>>> + "return a collection of classes which have a nil
>>> superclass"
>>> >>>>>> + ^ (self select: [:each | each isBehavior and: [each
>>> superclass
>>> >>>>>> isNil]]) asOrderedCollection.!
>>> >>>>>>
>>> >>>>>
>>> >>>>> At least for me this isn't quite good enough. There's a
>>> possibility that
>>> >>>>> someone could establish a variable whose value is a root,
>>> e.g. by
>>> >>>>>
>>> >>>>> Smalltalk at: #MyRootClass put: ProtoObject
>>> >>>>>
>>> >>>>> and that would cause rootClasses to answer a duplicate. So
>>> IMO it needs to
>>> >>>>> do one of
>>> >>>>> - convert to a set and then back to a collection
>>> >>>>> - answer a set
>>> >>>>> - enumerate over associations, selecting those classes whose
>>> key is the
>>> >>>>> same as their name
>>> >>>>>
>>> >>>>> _,,,^..^,,,_
>>> >>>>> best, Eliot
>>> >>>>
>>> >>>> Hi Eliot,
>>> >>>>
>>> >>>> Do you mean this?
>>> >>>>
>>> >>>> Environment>>rootClasses
>>> >>>> "return a collection of classes which have a nil superclass"
>>> >>>> ^ (self select: [:each | each isBehavior and: [each
>>> superclass isNil]]) asSet asOrderedCollection.
>>> >>>
>>> >>> That'll do but perhaps better is
>>> >>>
>>> >>> self bindings select: [:each | each value isBehavior
>>> and: [each value superclass isNil and: [each value name == each key]]])
>>> collect: [:each | each value]
>>> >>>
>>> >>>>
>>> >>>>
>>> >>>> Note, I am not the author here, just tending to the inbox :-)
>>> >>>>
>>> >>>> Thanks,
>>> >>>> Dave
>>> >>>>
>>> >>>>
>>> >>>
>>> >>
>>> >
>>>
>>>
>>>
>>>
>>> --
>>> _,,,^..^,,,_
>>> best, Eliot
>>>
>>
>>
>>
>
>
>
> --
> _,,,^..^,,,_
> best, Eliot
>
>
>
More information about the Squeak-dev
mailing list
|