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