I just created a small changeset
http://bugs.squeak.org/view.php?id=7432 which gives me a long awaited feature: to see in a browser, where the heck a given method comes from. If method comes from trait, a method's source tells me , from which one exactly! Open a browser on Behavior clas and select an #addExclusionOf:to: method. Usually you'll see: addExclusionOf: aSymbol to: aTrait self setTraitComposition: ( self traitComposition copyWithExclusionOf: aSymbol to: aTrait) But with my changes you'll see: " From: TAccessingTraitCompositionBehavior " addExclusionOf: aSymbol to: aTrait self setTraitComposition: ( self traitComposition copyWithExclusionOf: aSymbol to: aTrait) in code pane. Same applies to traits themselves for instance, browse TPureBehavior>>isAliasSelector: " From: TAccessingTraitCompositionBehavior " isAliasSelector: aSymbol "Return true if the selector aSymbol is an alias defined in my or in another composition somewhere deeper in the tree of traits compositions." ^(self includesLocalSelector: aSymbol) not and: [self hasTraitComposition] and: [self traitComposition isAliasSelector: aSymbol] There is one problem , which requires better expertise than mine and i need a help from Traits experts: an aliased methods. I tried to find out, how to dig out the aliased method from composition, and get its source to display in code pane .. but no luck. Please give me an advice, how a #getSourceCodeBySelector: method should be implemented for proper handling of aliases. Currently, all aliased methods sources shown using decompiler: Behavior>>methodDictAddSelectorSilently: t1 withMethod: t2 self basicAddSelector: t1 withMethod: t2 Aliased methods, obviously, will require an additional info in source header, like: " From: SomeTrait , originalSelector: #blablba " -- Best regards, Igor Stasenko AKA sig. |
A little more.
I made an experiment with compressing a method sources into trailers. (you need to file in a changeset (trailer-fixes-extensions.1.cs ) http://bugs.squeak.org/view.php?id=7428 What i did is: CompiledMethod allInstancesDo: [:m | m dropSourcePointer ] It takes a while (compressing sources). A more faster way is to do same in workspace: old := CompiledMethod allInstances select: [ :each | each trailer hasSourcePointer ]. new := old collect: [ :each | each copyWithTrailerBytes: (CompiledMethodTrailer new sourceCode: each getSource) ]. old elementsForwardIdentityTo: new. Before: Image size: 26,192,916 bytes After: Image size: 33,348,596 bytes difference: 7,155,680 bytes. But this means, that your image doesn't have to use .sources file, which is 17,584,724 bytes long as well as .changes 11,745,139 bytes long.. of course, stripping like this, will leave you without method stamps.. :) -- Best regards, Igor Stasenko AKA sig. |
In reply to this post by Igor Stasenko
Hi Igor,
This looks complicated... Note, in Pharo this does not work because there is no sharing of compiled methods from traits anymore. I attached a changeset that does the same as yours but for Pharo. The only thing that is needed are a few lines in sourceCodeAt:. The method #traitOrClassOfSelector: returns the origin of a method -- this should work just fine for aliased methods too. HTH, Adrian On Dec 21, 2009, at 01:09 , Igor Stasenko wrote: > I just created a small changeset > > http://bugs.squeak.org/view.php?id=7432 > > which gives me a long awaited feature: > to see in a browser, where the heck a given method comes from. > > If method comes from trait, a method's source tells me , from which > one exactly! > > Open a browser on Behavior clas and select an #addExclusionOf:to: > method. > Usually you'll see: > > addExclusionOf: aSymbol to: aTrait > self setTraitComposition: ( > self traitComposition copyWithExclusionOf: aSymbol to: aTrait) > > But with my changes you'll see: > > " From: TAccessingTraitCompositionBehavior " > addExclusionOf: aSymbol to: aTrait > self setTraitComposition: ( > self traitComposition copyWithExclusionOf: aSymbol to: aTrait) > > in code pane. > > Same applies to traits themselves for instance, browse > TPureBehavior>>isAliasSelector: > > " From: TAccessingTraitCompositionBehavior " > isAliasSelector: aSymbol > "Return true if the selector aSymbol is an alias defined > in my or in another composition somewhere deeper in > the tree of traits compositions." > > ^(self includesLocalSelector: aSymbol) not > and: [self hasTraitComposition] > and: [self traitComposition isAliasSelector: aSymbol] > > > There is one problem , which requires better expertise than mine and i > need a help from Traits experts: an aliased methods. > I tried to find out, how to dig out the aliased method from > composition, and get its source to display in code pane .. but no > luck. > Please give me an advice, how a #getSourceCodeBySelector: > method should be implemented for proper handling of aliases. > Currently, all aliased methods sources shown using decompiler: > > Behavior>>methodDictAddSelectorSilently: t1 withMethod: t2 > self basicAddSelector: t1 withMethod: t2 > > Aliased methods, obviously, will require an additional info in source > header, like: > > " From: SomeTrait , originalSelector: #blablba " > > -- > Best regards, > Igor Stasenko AKA sig. > > _______________________________________________ > Pharo-project mailing list > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project PrintTraitsMethodOrigin.1.cs (3K) Download Attachment |
2009/12/21 Adrian Lienhard <[hidden email]>:
> Hi Igor, > > This looks complicated... Hmm, i wonder, what Traits serve for, if requesting an original source code of method which being installed in specific behavior using specific selector becomes non-trivial task. > Note, in Pharo this does not work because there is > no sharing of compiled methods from traits anymore. > and it is good that there is no sharing, because in fact, my new code won't work if traits/behaviors sharing same CompiledMethod instances, because this could lead to recursion when looking for method's source code. I'm also made my own 'fix' for that by overriding the addTraitSelector: aSymbol withMethod: aCompiledMethod which ALWAYS makes a copy of aCompiledMethod before installing it into receiver's method dict and replaces its trailer with one that tells class to use #getSourceCodeBySelector: for finding its source code. (I hope this is the only entry method, which used by all traits to install the non-local method in behavior's method dict, if not, please tell me what other places should be fixed). I found that because squeak not doing that, there is a funky methods, which a) originally belong to some trait b) responding a behavior (not trait), where it installed when sending #methodClass a regression test is: Trait allSubInstancesDo:[:t | t methodDict do: [:m | self assert(m methodClass == t) ]] > I attached a changeset that does the same as yours but for Pharo. > Thanks, i'll take a look. > > > > > The only thing that is needed are a few lines in sourceCodeAt:. The method > #traitOrClassOfSelector: returns the origin of a method -- this should work > just fine for aliased methods too. > > HTH, > Adrian > > On Dec 21, 2009, at 01:09 , Igor Stasenko wrote: > >> I just created a small changeset >> >> http://bugs.squeak.org/view.php?id=7432 >> >> which gives me a long awaited feature: >> to see in a browser, where the heck a given method comes from. >> >> If method comes from trait, a method's source tells me , from which one >> exactly! >> >> Open a browser on Behavior clas and select an #addExclusionOf:to: method. >> Usually you'll see: >> >> addExclusionOf: aSymbol to: aTrait >> self setTraitComposition: ( >> self traitComposition copyWithExclusionOf: aSymbol to: >> aTrait) >> >> But with my changes you'll see: >> >> " From: TAccessingTraitCompositionBehavior " >> addExclusionOf: aSymbol to: aTrait >> self setTraitComposition: ( >> self traitComposition copyWithExclusionOf: aSymbol to: >> aTrait) >> >> in code pane. >> >> Same applies to traits themselves for instance, browse >> TPureBehavior>>isAliasSelector: >> >> " From: TAccessingTraitCompositionBehavior " >> isAliasSelector: aSymbol >> "Return true if the selector aSymbol is an alias defined >> in my or in another composition somewhere deeper in >> the tree of traits compositions." >> >> ^(self includesLocalSelector: aSymbol) not >> and: [self hasTraitComposition] >> and: [self traitComposition isAliasSelector: aSymbol] >> >> >> There is one problem , which requires better expertise than mine and i >> need a help from Traits experts: an aliased methods. >> I tried to find out, how to dig out the aliased method from >> composition, and get its source to display in code pane .. but no >> luck. >> Please give me an advice, how a #getSourceCodeBySelector: >> method should be implemented for proper handling of aliases. >> Currently, all aliased methods sources shown using decompiler: >> >> Behavior>>methodDictAddSelectorSilently: t1 withMethod: t2 >> self basicAddSelector: t1 withMethod: t2 >> >> Aliased methods, obviously, will require an additional info in source >> header, like: >> >> " From: SomeTrait , originalSelector: #blablba " >> >> -- >> Best regards, >> Igor Stasenko AKA sig. >> >> _______________________________________________ >> Pharo-project mailing list >> [hidden email] >> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project > > > > > -- Best regards, Igor Stasenko AKA sig. |
On Dec 21, 2009, at 13:36 , Igor Stasenko wrote: > 2009/12/21 Adrian Lienhard <[hidden email]>: >> Hi Igor, >> >> This looks complicated... > > Hmm, i wonder, what Traits serve for, if requesting an original source > code of method which being installed in specific behavior using > specific selector > becomes non-trivial task. Well, it *is* trivial -- at least with the version of the Traits implementation in Pharo. See the changeset I attached. Cheers, Adrian |
2009/12/21 Adrian Lienhard <[hidden email]>:
> > On Dec 21, 2009, at 13:36 , Igor Stasenko wrote: > >> 2009/12/21 Adrian Lienhard <[hidden email]>: >>> >>> Hi Igor, >>> >>> This looks complicated... >> >> Hmm, i wonder, what Traits serve for, if requesting an original source >> code of method which being installed in specific behavior using >> specific selector >> becomes non-trivial task. > > Well, it *is* trivial -- at least with the version of the Traits > implementation in Pharo. See the changeset I attached. > I found that in both trunk & pharo, aliases seem disfunctional. create Trait named: #Foo create method: Foo>>methodA . create Trait named: #Bar using: Foo @ {#methodA -> #methodB }. Bar shows a single method (methodA) ... but i expected to see #methodB instead. Same for classes.. Object subclass: #Zork uses: Bar .. shows methodA, not methodB in browser. I am doing something wrong? > Cheers, > Adrian > > -- Best regards, Igor Stasenko AKA sig. |
Yes, it also works for aliased methods.
It should be ... @ {#methodB -> #methodA} meaning methodB is an alias for methodA Cheers, Adrian On Dec 21, 2009, at 13:50 , Igor Stasenko wrote: > 2009/12/21 Adrian Lienhard <[hidden email]>: >> >> On Dec 21, 2009, at 13:36 , Igor Stasenko wrote: >> >>> 2009/12/21 Adrian Lienhard <[hidden email]>: >>>> >>>> Hi Igor, >>>> >>>> This looks complicated... >>> >>> Hmm, i wonder, what Traits serve for, if requesting an original >>> source >>> code of method which being installed in specific behavior using >>> specific selector >>> becomes non-trivial task. >> >> Well, it *is* trivial -- at least with the version of the Traits >> implementation in Pharo. See the changeset I attached. >> > will it work for aliased ones? > > I found that in both trunk & pharo, aliases seem disfunctional. > > create > Trait named: #Foo > > create method: > Foo>>methodA . > > create > Trait named: #Bar > using: Foo @ {#methodA -> #methodB }. > > Bar shows a single method (methodA) ... but i expected to see > #methodB instead. > > Same for classes.. > > Object subclass: #Zork > uses: Bar > .. > shows methodA, not methodB in browser. > I am doing something wrong? > >> Cheers, >> Adrian >> >> > > > > -- > Best regards, > Igor Stasenko AKA sig. > > _______________________________________________ > Pharo-project mailing list > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
2009/12/21 Adrian Lienhard <[hidden email]>:
> Yes, it also works for aliased methods. > > It should be ... @ {#methodB -> #methodA} meaning methodB is an alias for > methodA > So, the pattern is: @ { #newName -> #oldName } hmm.. then there is no wonder, since i interpret it differently , assuming that pattern is: @ { #existingName -> #aliasedName } because, as to me , by reading this expression its more natural to think that operand to the left of '->' is the 'initial' or 'original' state, and to the right - intended state, but not reverse. Otherwise, maybe its worth to use an explicit & different selector: @ { #aliasedName <- #existingName }. And in #<- create something other than Association, which will make trait definitions a bit more error proof , by not allowing associations in composition. (just guessing) Btw, it would be good to assert at such point, saying to user that he attempts to make an alias of non-existing method. > Cheers, > Adrian > > -- Best regards, Igor Stasenko AKA sig. |
Free forum by Nabble | Edit this page |