It will be interesting to see what the behavior of this issue is in swf9.<br><br><br><div class="gmail_quote">On Jan 9, 2008 5:37 PM, P T Withington <<a href="mailto:ptw@pobox.com">ptw@pobox.com</a>> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
yes please.<br><br>Simple test case is to compare the behaviour of the attribute and<br>method declarations.<br><br>It's a swf-only bug.<br><div><div></div><div class="Wj3C7c"><br>On 2008-01-09, at 17:34 EST, André Bargull wrote:
<br><br>> Should we create a JIRA-entry for this bug, so either to create a<br>> fix (somehow), or to document it at least.<br>><br>> - André<br>><br>> On 1/9/2008 11:07 PM, P T Withington wrote:<br>>> I take back my explanation regarding `this`.
<br>>><br>>> What it really is is a bug in the Flash implementation of "function<br>>> scope". When you define a function, it is supposed to capture the<br>>> scope that it was defined in (and use that scope to look up free
<br>>> references in). The Flash player makes a optimization of never<br>>> capturing the scope of a function defined in the global scope.<br>>> This would be fine, because you call all your functions in the
<br>>> global scope, so it will be there when you call.<br>>><br>>> BUT, Henry is right (as usual).<br>>><br>>> There are a bunch of places in the player where as functions are<br>>> being called by player internals (surely C or C++), and the player
<br>>> "forgets" to call the function in the global scope. The most<br>>> common place we run into this is in the idle loop. But apparently<br>>> the Array#sort method is another case. We used to have to write
<br>>> all our code that would be used in the idle loop to explicitly<br>>> reference everything from `_root` (which must somehow be specially<br>>> looked up, not just looked up in the scope chain).<br>
>><br>>> A while back, we worked around this issue by making sure that every<br>>> method we define is defined in such a way as to trick the runtime<br>>> into capturing the global scope on the function. It seems like
<br>>> that technique is not working 100%.<br>>><br>>> And it seems that when a free reference is made from a function and<br>>> the scope chain is empty, the function just immediately exits,<br>>> which is why you see no output.
<br>>><br>>> The (apparent) reason that tracing or closing over the function<br>>> works is that both are invoking the scope-less function inside a<br>>> function that _does_ have a scope, so it all works out.
<br>>><br>>> So, really, this is a bug in our compiler's work-around for the<br>>> scope issue. If you rewrite the canvas method as:<br>>><br>>> <attribute name="laszloMethod" value='function (n1, n2)
<br>>> { Debug.write("%s: %d - %d (%s)", arguments.callee, n1, n2, Debug);<br>>> return 0}' /><br>>><br>>> (which should be equivalent), everything works...<br>>><br>>> On 2008-01-09, at 16:13 EST, André Bargull wrote:
<br>>><br>>>> Another riddle for Tucker:<br>>>><br>>>> I can call:<br>>>> _root.Debug.write("%s: %d - %d", arguments.callee, n1, n2);<br>>>><br>>>> But I cannot call:
<br>>>> _root.Debug.write("%s: %d - %d (%s)", arguments.callee, n1, n2,<br>>>> Debug);//or i.e. global, canvas etc. breaks, too<br>>>><br>>>> So, in which context does get Array#sort(..) called?
<br>>>><br>>>>> It _is_ getting called. For some reason, your Debug.write is<br>>>>> failing to send any output:<br>>>>><br>>>>> lzx> Debug.trace(canvas, 'laszloMethod')
<br>>>>> lzx> [1,2,3].sort(canvas.laszloMethod)<br>>>>> TRACE: [394491.00] laszloMethod.apply(?undefined?, [1, 2])<br>>>>> laszloMethod( 1 , 2 )<br>>>>> TRACE: [394501.00
] laszloMethod -> 0<br>>>>> TRACE: [394505.00] laszloMethod.apply(?undefined?, [1, 3])<br>>>>> laszloMethod( 1 , 3 )<br>>>>> TRACE: [394512.00] laszloMethod -> 0<br>>>>> TRACE: [
394516.00] laszloMethod.apply(?undefined?, [1, 2])<br>>>>> laszloMethod( 1 , 2 )<br>>>>> TRACE: [394523.00] laszloMethod -> 0<br>>>>> TRACE: [394527.00] laszloMethod.apply(?undefined?, [2, 3])
<br>>>>> laszloMethod( 2 , 3 )<br>>>>> TRACE: [394536.00] laszloMethod -> 0<br>>>>> ?Array(3)#15| [1, 2, 3]?<br>>>>> lzx><br>>>>><br>>>>> Oh, hah-hah. I see why. Because laslzoMethod is a method, it
<br>>>>> expects a 'this' argument, and our compiler inserts an implicit<br>>>>> `with (this)` around your method body, but you are calling it as<br>>>>> a function, and `this` is undefined in that case (see the trace
<br>>>>> output above). So your code is turning into `with (undefined)`<br>>>>> and I bet that causes the global reference to Debug to fail.<br>>>>> Amusingly, tracing the method makes the debug output work. I
<br>>>>> can't really explain that.<br>>>>><br>>>>> If you were to make a closure to call your method, it should work:<br>>>>><br>>>>> lzx> Debug.untrace(canvas, 'laszloMethod')
<br>>>>> lzx> [1,2,3].sort(function (a, b) { return canvas.laszloMethod(a,<br>>>>> b) })<br>>>>> laszloMethod( 1 , 2 )<br>>>>> laszloMethod( 1 , 3 )<br>>>>> laszloMethod( 1 , 2 )
<br>>>>> laszloMethod( 2 , 3 )<br>>>>> ?Array(3)#57| [1, 2, 3]?<br>>>>> lzx><br>>>>><br>>>>> On 2008-01-09, at 14:28 EST, Pablo Kang wrote:<br>>>>>
<br>>>>><br>>>>>> Btw, I know that I can call a laszloMethod from a Javascript<br>>>>>> function like:<br>>>>>><br>>>>>> <method name="javascriptFunction" args="n1,n2">
<br>>>>>> return canvas.laszloMethod(n1,n2);<br>>>>>> </method><br>>>>>><br>>>>>> What I want to know is why it is I can't pass in the the<br>>>>>> laszloMethod directly.
<br>>>>>><br>>>>>> Thanks,<br>>>>>> pablo<br>>>>>><br>>>>>> On Wed, 9 Jan 2008, Pablo Kang wrote:<br>>>>>><br>>>>>><br>
>>>>>> Anyone know why passing in a function defined with an LZX<br>>>>>>> method tag into Array.sort doesn't work? Here's a test case:<br>>>>>>><br>>>>>>> <canvas debug="true">
<br>>>>>>><br>>>>>>> <method name="laszloMethod" args="n1,n2"><br>>>>>>> Debug.write('laszloMethod(', n1, ',', n2, ')');
<br>>>>>>> return 0;<br>>>>>>> </method><br>>>>>>><br>>>>>>> <script><br>>>>>>> function javascriptFunction(n1,n2) {
<br>>>>>>> Debug.write('javascriptFunction(', n1, ',', n2 ,')');<br>>>>>>> return 0;<br>>>>>>> }<br>>>>>>> </script>
<br>>>>>>><br>>>>>>> <handler name="oninit"><br>>>>>>> var arr = [ 1,2,3 ];<br>>>>>>><br>>>>>>> Debug.write
('-- Javascript Function --');<br>>>>>>> arr.sort( javascriptFunction );<br>>>>>>><br>>>>>>> Debug.write('-- Laszlo Method --------');<br>>>>>>>
arr.sort( canvas.laszloMethod );<br>>>>>>> </handler><br>>>>>>><br>>>>>>> </canvas><br>>>>>>><br>>>>>>> pablo<br>>>>>>>
<br>>>>>>><br>>>>>>><br>>>>>>><br>>>>><br>>>>><br>>>><br>>><br>>><br>><br><br><br></div></div></blockquote></div><br><br clear="all">
<br>-- <br>Henry Minsky<br>Software Architect<br><a href="mailto:hminsky@laszlosystems.com">hminsky@laszlosystems.com</a><br><br>