<br><br><div class="gmail_quote">On Tue, Jul 7, 2009 at 3:58 PM, David Goehrig <span dir="ltr">&lt;<a href="mailto:dave@nexttolast.com">dave@nexttolast.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Dear Squeakers,<div><br></div><div>I have a question for some of Squeak gurus on the list.  I&#39;ve been porting a javascript project I did a couple months back to Squeak, and in the process of porting it, added an ad hoc object class that handled the prototype based inheritance I used in the javascript version.</div>

<div><br></div><div>One of the issues I encountered was that when I did a copy of my object, the block closures supplied for various properties required a bit of a hack so I have a method:</div><div><br></div><div><div><div>

<div>doesNotUnderstand: aMessage</div><div><span style="white-space:pre">        </span>&quot;Generic catch all that performs all selectors&quot;</div><div><span style="white-space:pre">        </span>(self can: aMessage selector) ifTrue: [ </div>

<div><span style="white-space:pre">                </span>(self s: aMessage selector ) outerContext receiver: self. </div><div><span style="white-space:pre">                </span>^( self s: aMessage selector )valueWithEnoughArguments: aMessage arguments ].</div>

<div><span style="white-space:pre">        </span>^ self s: aMessage selector.</div></div></div><div><br></div><div>Now this seems to do exactly what I wanted 99% of the time.  It mimics the behavior of using a block closure as a javascript function() {} object, and all other objects are returned as intended.  The #s: method returns nil if the property is not found in the object&#39;s dictionary as well, and #can: is just a fancy way to test if the property is a block closure.  By using valueWithEnoughArguments: it even gets padded out with nils like JS would.</div>

<div><br></div><div><div>I&#39;m not entirely happy with how hackish this seems, patching the outerContext and then re-rolling the arguments array to one of the proper size just to copy into a MethodContext. </div><div><br>

</div></div><div>My question is &quot;Is there a better way?&quot;</div></div></blockquote><div><br></div><div>You could do something analogous with messages and methods an d have the Vm associate the receiver with the activation in... a message send :)</div>
<div>If you had a dictionary that cached translations form short forms of selectors, e.g. myJSFunc:with: -&gt; myJSFunc:with:with: then your code might look something like</div><div><br></div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; "><div>
doesNotUnderstand: aMessage</div><div><span style="white-space: pre; ">        </span>&quot;Generic catch all that performs all selectors&quot;</div></span><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; white-space: pre; ">        </span>(self can: aMessage selector) ifTrue:</div>
<div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; white-space: pre; ">                <span class="Apple-style-span" style="border-collapse: separate; font-family: arial; font-size: small; white-space: normal; ">[actualSelector := self s: aMessage selector.</span></span></div>
<div><span class="Apple-style-span" style="font-family: arial, sans-serif; border-collapse: collapse; white-space: pre; "></span></div><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; white-space: pre; ">                 ^<span class="Apple-style-span" style="border-collapse: separate; font-family: arial; font-size: small; white-space: normal; ">self perform: actualSelector</span></span></div>
<div><span class="Apple-style-span" style="font-family: arial, sans-serif; border-collapse: collapse; white-space: pre; "></span></div><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; white-space: pre; ">                        <span class="Apple-style-span" style="border-collapse: separate; font-size: small; white-space: normal; ">withArguments: (aMessage arguments, (Array new: actualSelector numArgs - aMessage selector numArgs))]</span></span></div>
<div><span class="Apple-style-span" style="font-family: arial, sans-serif; border-collapse: collapse; white-space: pre; "></span></div><div><br></div><div>Would this be better?</div><div><br></div><div>You can then adapt this pattern and compile adaptors on the fly to something like</div>
<div><br></div><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; "><div>doesNotUnderstand: aMessage</div><div><span style="white-space: pre; ">        </span>&quot;Generic catch all that performs all selectors&quot;</div>
</span><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; white-space: pre; ">        </span>(self can: aMessage selector) ifTrue:</div><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; white-space: pre; ">                <span class="Apple-style-span" style="border-collapse: separate; font-family: arial; font-size: small; white-space: normal; ">[self compile: (self adapt: aMessage selector to: (self s: aMessage selector) classified: #&#39;message adaptors&#39;.</span></span></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="font-size: 13px; border-collapse: collapse; white-space: pre; ">                 ^self perform: aMessage selector withArguments: aMessage arguments</span></font></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse; white-space: pre;"><br></span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse; white-space: pre;">or</span></font></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse; white-space: pre;"><br></span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse; white-space: pre;"><span class="Apple-style-span" style="border-collapse: separate; font-family: arial; white-space: normal; "><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; "><div>
doesNotUnderstand: aMessage</div><div><span style="white-space: pre; ">        </span>&quot;Generic catch all that performs all selectors&quot;</div></span><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; white-space: pre; ">        </span>(self can: aMessage selector) ifTrue:</div>
<div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; white-space: pre; ">                <span class="Apple-style-span" style="border-collapse: separate; font-family: arial; font-size: small; white-space: normal; ">[self compileAdaptorFor: aMessage selector to: (self s: aMessage selector).</span></span></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="font-size: 13px; border-collapse: collapse; white-space: pre; ">                 ^self perform: aMessage selector withArguments: aMessage arguments</span></font></div>
<div><span class="Apple-style-span" style="border-collapse: collapse; white-space: pre;"><span class="Apple-style-span" style="border-collapse: separate; white-space: normal; "><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse; white-space: pre; "><br>
</span></font></div></span></span></div></span></span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse; white-space: pre;">so the doesNotUnderstand: would be invoked first-time only (echos of the Borning-Ingalls multiple inheritance implementation).  adapt:to: would return the text of a method that supplied nils for missing arguments (note it is pretty trivial to add default values with this pattern).  Decorate the method with a pragma to mark it as auto-generated, e.g.  adapt: #myMessage: to: #myMessage:with: might answer</span></font></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse; white-space: pre;">&#39;myMessage: arg1</span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse; white-space: pre;">    &lt;adaptorFor: #myMessage:with:&gt;</span></font></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse; white-space: pre;">    ^self myMessage: arg1 with: nil&#39;</span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse; white-space: pre;"><br>
</span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse; white-space: pre;">Then you can easily flush generated adaptors (e.g. before writing out an MC package, could also merely use the category to corral adaptors).</span></font></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse; white-space: pre;"><br></span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse; white-space: pre;">Yes?</span></font></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse; white-space: pre;"><br></span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse; white-space: pre;">best</span></font></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse; white-space: pre;">Eliot</span></font></div><div><span class="Apple-style-span" style="font-family: arial, sans-serif; border-collapse: collapse; white-space: pre; "></span></div>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div><div></div><div><br></div><div>Dave</div></div><div><br>-- <br>-=-=-=-=-=-=-=-=-=-=- <a href="http://blog.dloh.org/" target="_blank">http://blog.dloh.org/</a><br>

</div>
<br><br>
<br></blockquote></div><br>