<br><br><div class="gmail_quote">On Tue, Jul 7, 2009 at 3:58 PM, David Goehrig <span dir="ltr"><<a href="mailto:dave@nexttolast.com">dave@nexttolast.com</a>></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'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>"Generic catch all that performs all selectors"</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'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'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 "Is there a better way?"</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: -> 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>"Generic catch all that performs all selectors"</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>"Generic catch all that performs all selectors"</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: #'message adaptors'.</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>"Generic catch all that performs all selectors"</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;">'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;"> <adaptorFor: #myMessage:with:></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'</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>