<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<div id="divtagdefaultwrapper" style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p>(Forking this thread due to difference of concerns ... :-))</p>
<p><br>
</p>
<p></p>
<div>> I'm also not sure whether these methods belong to ProtoObject or not.</div>
<div><br>
</div>
<div>This is an interesting problem, see also the recent thread about cleaning up ProtoObject. I agree with Eliot that a good ProtoObject is as small and stupid as possible in order to be really useful for writing powerful proxies or decorators. It should be
 possible to wrap nil into an ObjectTracer, for example! To put the issue in a nutshell, try out the following:</div>
<div><br>
</div>
<p></p>
</div>
<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p></p>
<div>newNil := UndefinedObject basicNew.</div>
<p></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p></p>
<div>nilTracer := ObjectTracer on: newNil.</div>
<p></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p></p>
<div>nilTracer isNil. "false"</div>
<p></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p></p>
<div>nilTracer perform: #isNil. "true"</div>
<p></p>
</div>
</blockquote>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p></p>
<div><br>
</div>
<div>Here's a similar issue:</div>
<div><br>
</div>
<p></p>
</div>
<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p></p>
<div>
<div>specialClass := Object newSubclass.</div>
<div>specialClass compile: 'class ^42'.</div>
<div>specialObj := specialClass new.</div>
<div>specialObj class. "Object1"</div>
<div><span>specialObj perform: #class. "42"</span><br>
</div>
</div>
</div>
</blockquote>
<div><br>
</div>
<div>(By the way, we are not even consistent with ourself in this concern:</div>
<br>
<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div>
<div>([specialObj class] newProcess runUntil: #willReturn) suspendedContext top. "42"</div>
</div>
<p></p>
</div>
</blockquote>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p></p>
<div><br>
</div>
<div>) <span style="font-size: 12pt;">Pooh, that's both really not nice ... Basically, inlining of #isNil & Co. is an optimization and IMHO it should not affect the basic concept of how messages are dispatched. Too less inlining affects performance, but too
 much inlining introduces conceptional errors.</span></div>
<div>Would it be a big performance impact if we made inlining optional? Here is a short proposal:</div>
<div><br>
</div>
<div>We could tell every bytecode interpreter to check for any receiver if it agrees on being deprived of messages that can be inlined. We could decide this per receiver class and cache these answers in the VM. Hypothetical example:</div>
<div><br>
</div>
<p></p>
</div>
<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p></p>
<div>Object >> #acceptsInlining</div>
<p></p>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p></p>
<div>    "This message is never sent, but it's existance signalizes the VM that it is okay to inline popular messages such as #isNil or #ifTrue:."</div>
<p></p>
</div>
</blockquote>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p></p>
<div><br>
</div>
<div>If this concept is too expensive or too confusing, we could also add an instance variable to the class object. Anyway, something like this. That way we could make the concept of inlining optional. If an interpreter evaluated {nilTracer isNil}, it would
 have to do the following (I'm following the simulation code in #interpretNextSistaV1InstructionFor:. Disclaimer: Absolutely free of optimizations!)</div>
<div><br>
</div>
</div>
<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div>...</div>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div>"short sends"</div>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div>(div16 = 6 <b>and: [rcvr respondsTo: #acceptsInlining]</b>) ifTrue:</div>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div><span style="white-space:pre"></span>[^client</div>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div><span style="white-space:pre"></span>send: (Smalltalk specialSelectorAt: offset + 1)</div>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div><span style="white-space:pre"></span>super: false</div>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div><span style="white-space:pre"></span>numArgs: (Smalltalk specialNargsAt: offset + 1)].</div>
<div>...</div>
<div>"otherwise, message will be dispatched regularly"</div>
</div>
</blockquote>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div><br>
</div>
<div>Some similar checks would be required in case of primitives that are generated for inlined methods, such as 257f.:</div>
<div><br>
</div>
</div>
<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div>...</div>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div>((primIndex := meth primitive) > 0 <b>and: [</b></div>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div><b>        (self isInliningPrimitive: primitive) not or: [rcvr respondsTo: #acceptsInlining]]</b>)</div>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div>ifTrue:</div>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div>    [val := self doPrimitive: primIndex method: meth receiver: rcvr args: arguments.</div>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div>    (self isPrimFailToken: val) ifFalse:</div>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div>        [^val]]</div>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div>...</div>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div>"otherwise, message will be dispatched regularly"</div>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div></div>
</div>
</blockquote>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<br>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
How would you think of this concept in general? I'm excited to hear your feedback! :-)</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<br>
</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
Best,</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
Christoph</div>
<div style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<div></div>
<p></p>
<br>
<div style="color: rgb(0, 0, 0);">
<div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="x_divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>Von:</b> Squeak-dev <squeak-dev-bounces@lists.squeakfoundation.org> im Auftrag von Levente Uzonyi <leves@caesar.elte.hu><br>
<b>Gesendet:</b> Samstag, 21. März 2020 20:25 Uhr<br>
<b>An:</b> The general-purpose Squeak developers list<br>
<b>Betreff:</b> Re: [squeak-dev] #isNilOr:, #notNilAnd:</font>
<div> </div>
</div>
</div>
<font size="2"><span style="font-size:10pt;">
<div class="PlainText">Hi Christoph,<br>
<br>
They are okay for scripts, but we know that methods like that always end <br>
up being used out of scripts, and are even misused every now and then.<br>
They are especially susceptible to misuse when their return value is <br>
ignored; in which case they are both equivalent to #ifNotNil:.<br>
<br>
I'm also not sure whether these methods belong to ProtoObject or not.<br>
I know the other nil handling methods are there as well, but that doesn't <br>
mean all such methods belong there.<br>
E.g. #ifNil:/#ifNotNil: should be there because the current compiler and <br>
VM will make those available for all objects provided the methods are <br>
inlined. But #isNil and #notNil have no such properties, so they belong <br>
more to Object than ProtoObject in my opinion.<br>
<br>
<br>
Levente<br>
<br>
On Mon, 16 Mar 2020, Thiede, Christoph wrote:<br>
<br>
> <br>
> Hi all,<br>
> <br>
> <br>
> after the release has been managed successfully, I would like to kindly push this proposal. In the latest months, I found myself to really often desiring #isNilOr: or #notNilAnd:. How would you think about these convenience<br>
> selectors? :-)<br>
> <br>
> <br>
> Best,<br>
> <br>
> Christoph<br>
> <br>
> _________________________________________________________________________________________________________________________________________________________________________________________________________________________________<br>
> Von: Thiede, Christoph<br>
> Gesendet: Mittwoch, 11. Dezember 2019 11:01:44<br>
> An: Squeak Dev<br>
> Betreff: #isNilOr:, #notNilAnd:  <br>
> <br>
> Hi all, just another idea for a hypothetic extension to ProtoObject:<br>
> <br>
> <br>
> ProtoObject >> #isNilOr: aBlock<br>
> <br>
> ^ aBlock cull: self<br>
> <br>
> UndefinedObject >> #isNilOr: aBlock<br>
> <br>
> ^ true<br>
> <br>
> ProtoObject >> #notNilAnd: aBlock<br>
> <br>
> ^ aBlock cull: self<br>
> <br>
> UndefinedObject >> #notNilAnd: aBlock<br>
> <br>
> ^ false<br>
> <br>
> <br>
> Examples:<br>
> <br>
> parentObject notNilAnd: #canBrowseSubtopic.<br>
> <br>
> helpClass notNilAnd: [:hC| hC usesCodeStyling].<br>
> <br>
> self selectionIndex isNilOr: [:index | index > 2].<br>
> <br>
> anObject isNilOr: #isZero.<br>
> <br>
> foo isNilOr: #isNotEmpty.<br>
> <br>
> <br>
> Just a bit syntactic sugar for idiomatic problems such as below. In particular, I found several possible applications for #notNilAnd: in my image.<br>
> <br>
> <br>
> Go ahead and tell me why it would be a bad idea :)<br>
> <br>
> <br>
> Best,<br>
> <br>
> Christoph<br>
> <br>
> <br>
> _________________________________________________________________________________________________________________________________________________________________________________________________________________________________<br>
> Von: Squeak-dev <squeak-dev-bounces@lists.squeakfoundation.org> im Auftrag von Thiede, Christoph<br>
> Gesendet: Freitag, 25. Oktober 2019 19:21 Uhr<br>
> An: gettimothy via Squeak-dev<br>
> Betreff: Re: [squeak-dev] The Inbox: HelpSystem-Core-ct.123.mcz  <br>
> <br>
> If you're needing a decision, I'd vote for option 3.<br>
> <br>
> _________________________________________________________________________________________________________________________________________________________________________________________________________________________________<br>
> Von: Squeak-dev <squeak-dev-bounces@lists.squeakfoundation.org> im Auftrag von Taeumel, Marcel<br>
> Gesendet: Mittwoch, 16. Oktober 2019 11:14:15<br>
> An: gettimothy via Squeak-dev<br>
> Betreff: Re: [squeak-dev] The Inbox: HelpSystem-Core-ct.123.mcz  <br>
> Quick suggestion on the formatting. This one:<br>
> ^ self canBrowseTopic or: [<br>
>    parentTopic ifNotNil: #canBrowseSubtopic ifNil: [false]]<br>
> <br>
> could become:<br>
> <br>
> ^ self canBrowseTopic or: [<br>
>    parentTopic<br>
>    ifNil: [false]<br>
>    ifNotNil: [:topic | topic canBrowseSubtopic]]<br>
> <br>
> or:<br>
> <br>
> ^ self canBrowseTopic<br>
>       or: [parentTopic notNil and: [parentTopic canBrowseSubtopic]]<br>
> <br>
> Hmmm... what are other opinions on this? There is no need for #ifNil/ifNotNil in such a boolean expression?<br>
> <br>
> Best,<br>
> Marcel<br>
> <br>
><br>
>       Am 13.10.2019 21:04:19 schrieb commits@source.squeak.org <commits@source.squeak.org>:<br>
><br>
>       A new version of HelpSystem-Core was added to project The Inbox:<br>
>       <a href="http://source.squeak.org/inbox/HelpSystem-Core-ct.123.mcz" id="LPlnk370798" previewremoved="true">
http://source.squeak.org/inbox/HelpSystem-Core-ct.123.mcz</a><br>
><br>
>       ==================== Summary ====================<br>
><br>
>       Name: HelpSystem-Core-ct.123<br>
>       Author: ct<br>
>       Time: 13 October 2019, 9:04:08.373932 pm<br>
>       UUID: dec7ceca-320f-d945-8d2a-c2f6a5e49a52<br>
>       Ancestors: HelpSystem-Core-ct.120<br>
><br>
>       Refactors HelpBrowser menu: Move menu stuff from HelpBrowser into HelpTopic hierarchy in favor of a better object design<br>
><br>
>       Thanks again, Marcel :-)<br>
><br>
>       =============== Diff against HelpSystem-Core-ct.120 ===============<br>
><br>
>       Item was added:<br>
>       + ----- Method: AbstractHelpTopic>>browseTopicFromParent: (in category 'tools') -----<br>
>       + browseTopicFromParent: parentTopic<br>
>       +<br>
>       + self canBrowseTopic<br>
>       + ifTrue: [^ self browseTopic].<br>
>       + parentTopic canBrowseSubtopic<br>
>       + ifTrue: [^ parentTopic browseSubtopic: self].<br>
>       + !<br>
><br>
>       Item was added:<br>
>       + ----- Method: AbstractHelpTopic>>canBrowseSubtopic (in category 'testing') -----<br>
>       + canBrowseSubtopic<br>
>       +<br>
>       + ^ false!<br>
><br>
>       Item was added:<br>
>       + ----- Method: AbstractHelpTopic>>canBrowseTopic (in category 'testing') -----<br>
>       + canBrowseTopic<br>
>       +<br>
>       + ^ false!<br>
><br>
>       Item was added:<br>
>       + ----- Method: AbstractHelpTopic>>canBrowseTopicFromParent: (in category 'testing') -----<br>
>       + canBrowseTopicFromParent: parentTopic<br>
>       +<br>
>       + ^ self canBrowseTopic or: [<br>
>       + parentTopic ifNotNil: #canBrowseSubtopic ifNil: [false]]!<br>
><br>
>       Item was added:<br>
>       + ----- Method: AbstractHelpTopic>>topicMenu:parentTopic: (in category 'menus') -----<br>
>       + topicMenu: aMenu parentTopic: parentTopic<br>
>       +<br>
>       + aMenu<br>
>       + add: 'Inspect (i)' translated target: self action: #inspect;<br>
>       + add: 'Explore (I)' translated target: self action: #explore.<br>
>       + (self canBrowseTopicFromParent: parentTopic)<br>
>       + ifTrue: [<br>
>       + aMenu add: 'Browse (b)' translated<br>
>       + target: self<br>
>       + selector: #browseTopicFromParent:<br>
>       + argumentList: {parentTopic} ].<br>
>       +<br>
>       + ^ aMenu!<br>
><br>
>       Item was added:<br>
>       + ----- Method: AbstractHelpTopic>>topicMenuKey:fromParent: (in category 'menus') -----<br>
>       + topicMenuKey: aChar fromParent: parentTopic<br>
>       +<br>
>       + aChar<br>
>       + caseOf: {<br>
>       + [$b] -> [(self canBrowseTopicFromParent: parentTopic)<br>
>       + ifTrue: [ self browseTopicFromParent: parentTopic ]].<br>
>       + [$i] -> [self inspect].<br>
>       + [$I] -> [self explore] }<br>
>       + otherwise: [^ false].<br>
>       + ^ true!<br>
><br>
>       Item was added:<br>
>       + ----- Method: ClassAPIHelpTopic>>canBrowseTopic (in category 'testing') -----<br>
>       + canBrowseTopic<br>
>       +<br>
>       + ^ true!<br>
><br>
>       Item was added:<br>
>       + ----- Method: ClassBasedHelpTopic>>canBrowseSubtopic (in category 'testing') -----<br>
>       + canBrowseSubtopic<br>
>       +<br>
>       + ^ true!<br>
><br>
>       Item was added:<br>
>       + ----- Method: ClassBasedHelpTopic>>canBrowseTopic (in category 'testing') -----<br>
>       + canBrowseTopic<br>
>       +<br>
>       + ^ true!<br>
><br>
>       Item was added:<br>
>       + ----- Method: DirectoryBasedHelpTopic>>canBrowseTopic (in category 'testing') -----<br>
>       + canBrowseTopic<br>
>       +<br>
>       + ^ true!<br>
><br>
>       Item was added:<br>
>       + ----- Method: FileBasedHelpTopic>>canBrowseTopic (in category 'testing') -----<br>
>       + canBrowseTopic<br>
>       +<br>
>       + ^ true!<br>
><br>
>       Item was removed:<br>
>       - ----- Method: HelpBrowser>>browseTopic (in category 'actions') -----<br>
>       - browseTopic<br>
>       -<br>
>       - ^ (self currentTopic respondsTo: #browseTopic)<br>
>       - ifTrue: [self currentTopic browseTopic]<br>
>       - ifFalse: [self currentParentTopic browseSubtopic: self currentTopic]!<br>
><br>
>       Item was removed:<br>
>       - ----- Method: HelpBrowser>>canBrowseTopic (in category 'testing') -----<br>
>       - canBrowseTopic<br>
>       -<br>
>       - ^ (self currentTopic respondsTo: #browseTopic)<br>
>       - or: [self currentParentTopic respondsTo: #browseSubtopic:]!<br>
><br>
>       Item was removed:<br>
>       - ----- Method: HelpBrowser>>exploreTopic (in category 'actions') -----<br>
>       - exploreTopic<br>
>       -<br>
>       - ^ self currentTopic explore!<br>
><br>
>       Item was removed:<br>
>       - ----- Method: HelpBrowser>>inspectTopic (in category 'actions') -----<br>
>       - inspectTopic<br>
>       -<br>
>       - ^ self currentTopic inspect!<br>
><br>
>       Item was changed:<br>
>       ----- Method: HelpBrowser>>treeKey:from:event: (in category 'menus') -----<br>
>       treeKey: aChar from: aView event: anEvent<br>
><br>
>       anEvent anyModifierKeyPressed ifFalse: [^ false].<br>
>       + ^ (self currentTopic topicMenuKey: aChar fromParent: self currentParentTopic)!<br>
>       - aChar<br>
>       - caseOf: {<br>
>       - [$b] -> [self browseTopic].<br>
>       - [$i] -> [self inspectTopic].<br>
>       - [$I] -> [self exploreTopic]. }<br>
>       - otherwise: [^ false].<br>
>       - ^ true!<br>
><br>
>       Item was changed:<br>
>       ----- Method: HelpBrowser>>treeListMenu: (in category 'menus') -----<br>
>       treeListMenu: aMenu<br>
> <br>
><br>
>       + ^ self currentTopic<br>
>       + ifNil: [aMenu]<br>
>       + ifNotNil: [:topic | topic<br>
>       + topicMenu: aMenu<br>
>       + parentTopic: self currentParentTopic]!<br>
>       - self currentTopic ifNil: [^ aMenu].<br>
>       -<br>
>       - aMenu<br>
>       - add: 'Inspect (i)' action: #inspectTopic;<br>
>       - add: 'Explore (I)' action: #exploreTopic.<br>
>       -<br>
>       - self canBrowseTopic ifTrue: [<br>
>       - aMenu<br>
>       - addLine;<br>
>       - add: 'Browse (b)' action: #browseTopic].<br>
>       -<br>
>       - ^ aMenu!<br>
><br>
>       Item was added:<br>
>       + ----- Method: MethodListHelpTopic>>canBrowseTopic (in category 'testing') -----<br>
>       + canBrowseTopic<br>
>       +<br>
>       + ^ true!<br>
><br>
>       Item was added:<br>
>       + ----- Method: PackageAPIHelpTopic>>canBrowseTopic (in category 'testing') -----<br>
>       + canBrowseTopic<br>
>       +<br>
>       + ^ true!<br>
> <br>
> <br>
> <br>
></div>
</span></font></div>
</div>
</div>
</body>
</html>