On 2007-10-03, at 18:00 EDT, André Bargull wrote:

If got a couple of questions regarding this changeset:
1. Debug.write([void(0)]) will now print "[undefined]", beforehand it was "[...]" Undefined values were explicitly skipped prior to this change (see i.e. LzDebug.as (old), ll.358: /"skip non-existent elements"/)
   This behaviour has changed => intentionally or not?

This is actually a correction. In very old swf runtimes, you could not tell the difference between a non-existent property and a property whose value is undefined. Now we can, so I think it is more honest for the debugger to print these properties than to skip them.

2. Debug.write({length:'0'}) will now print "«Object#0| []»", beforehand it was "{length: 0}" Additional test for type of the length-attribute, "string" vs. "number"?

Good point.  I will fix that.

3. SWF vs. DHTML: to create a common code base, you've removed some try..catch blocks (see LzDebug.js (old), l.462 to l.483)
   Any disadvantages possible through this change?

I think the advantages out-weigh the disadvantages. A) I put that particular try/catch in early on when I was just trying to get the debugger working at all in DHTML, B) It seems bad form to just discard errors silently. Finally, now that we have Firebug, if we do hit an error here, hopefully we can fix it.

4. SWF vs. DHTML: /"getter-heuristic"/ Debug#inspectInternal(..) resp. Debug#objectOwnProperties(..), less tests in SWF and removed try..catch in DHTML, no disadvantages at all for this?
      SWF:
       if ((! hasProto) ||
           obj.hasOwnProperty(key) ||
// attached movie clips don't show up as 'hasOwnProperty' (but // hasOwnProperty is more accurate -- consider if an instance
           // copies a prototype property)
           (obj[key] !== obj.__proto__[key]) ||
// or getter slots (this is a heuristic -- there is no way to
           // ask if a property is a getter)
           *(obj.__proto__.hasOwnProperty(key) &&
            (typeof(obj.__proto__[key]) == 'undefined'))*
       )

      DHTML:
       if ((! hasProto) ||
           obj.hasOwnProperty(key) ||
// or getter slots (this is a heuristic -- there is no way to
           // ask if a property is a getter)
*(function () { try { return obj[key] } catch (e) {} }) () !== (function () { try { return obj.constructor.prototype [key] } catch (e) {} })()*
           )

      NEW:
       if ((! hopp) ||
           obj.hasOwnProperty(key) ||
// Heuristic to find getter slots (there is no way to ask if a
           // property is a getter)
           (proto && (obj[key] !== proto[key])))

I am pretty sure that the new test subsumes both heuristics. Any time the value of a property in an object is different from that same property in the object's prototype, it is probably 'interesting' to the debugger. I'm not trying to be perfect here in any case, I am just trying to show the properties of an object, but not show zillions of inherited properties (they are probably less interesting).

It's not an error in JS to ask for a non-existent property, so the try/catches should be superfluous. They probably have the same origin as the one discussed above: just inserted randomly to try to get the debugger working.

5. Debug#__String(..): changes for treatment of objects with a (numeric) "length" property. Beforehand: any object with a numeric length property was treated as an array, "toString()" was never called,
                       see i.e. LzDebug.as (old), l.349 and ll.376
Now: if any object has got an own "toString()" method, it will called, so no treatment as an array,
                       see i.e. LzDebug.as (new), ll.348 and ll.360
      Good change, but do we need to document it?

In general I have not been documenting this level of cosmetic change in the debugger -- I guess now that there are lots of users out there, I should be more deliberate. Do you think it important to document this level of change? I tend to think of the debugger as constantly evolving and it not being critical that minor changes like this be documented.

Improvements:
- LzDebug.as, l.349 (new), "(thing['toString'] instanceof Function) &&" ==> "(thing.toString instanceof Function) &&" - LzDebug.as, l.563 (old), "var kl = keys.length;", LzDebug.as, l. 541 (new), "var kl = names.length;" "kl = [k]eys.[l]ength", but "kl = names.[l]ength"? (also for "var kil" and the same vars in LzDebug.js)
       Could be changed for clarification...

Noted.  Will fix.

Bug?:
- LzDebug.js, l.289 (new), "(this.toString instanceof Function)" should be "(thing.toString instanceof Function)"!?

Well spotted!  Thanks!

P T Withington wrote:
[André, if you are not up for reviewing this, let me know and I will get someone else, but I thought you might be an interested party...]

Change 20070930-ptw-P by [EMAIL PROTECTED] on 2007-09-30 18:01:29 EDT
    in /Users/ptw/OpenLaszlo/ringding-2
    for http://svn.openlaszlo.org/openlaszlo/trunk

Summary: Don't trust length as an indicator of array elements

Bugs Fixed:
LPP-4441 'Debugger misbehaves when debugging objects with "length" attribute.'

Technical Reviewer: [EMAIL PROTECTED] (pending)
QA Reviewer: hminsky (pending)
Doc Reviewer: jsundman (pending)

Documentation:
NOTE:  If you have Firebug enabled in Firefox, the LZX debugger echos
all messages to the Firebug console, preserving objects.  The Firebug
debugger will attempt to interpret an object with a `length` field as
an array and try to print every array element.  This may cause a
'Script Running Slowly' error.  Disabling Firebug will prevent that.

Details:
    Don't trust length to indicate how many properties are in an
    object (or elements in an array).  Instead, get the properties
    from the object using `for ... in`.  We still present any object
    with a `length` property that is non-negative as an array, but we
won't try to iterate through the entire array. This is useful for
    sparse arrays, but also for objects that just happen to have a
    non-negative length property.

    LzDebug.lzs:  Added Debug.objectOwnProperties that gets the names
    of all the 'own' properties of the object.  If the object has a
non-negative `length` property, accumulate the properties that are
    between 0 and that length in a separate list of indices.

LzDebug.{as,js}: Use that to print and inspect objects and arrays
    without falling into the trap of iterating from 0 to length.
Basically, the old presentation style is preserved, but we iterate
    _only_ over the properties the object actually has.

Tests:
lzx> Debug.write({1: 'one', 97: 'ninety-seven', a: 'eh?', floogle: 'snort', length: 100000000, __proto__: {bar: 'bletch'}})
    «Object(100000000)#127| [..., one, ..., ninety-seven]»
    lzx> Debug.inspect([..., one, ..., ninety-seven])
    «Object(100000000)#127| [..., one, ..., ninety-seven]» {
      a: 'eh?'
      floogle: 'snort'
      length: 100000000
      1: 'one'
      97: 'ninety-seven'
    }
    [..., one, ..., ninety-seven]
    lzx>

    Above completes without "Script Running Slowly".  Tested in SWF
    and DHTML (with Firebug disabled, see Documentation NOTE above).

    smokecheck passes in DHTML and SWF (which tests Debug.format,
which uses __String, showing that the expected presentation is preserved).

Files:
M      WEB-INF/lps/lfc/debugger/LzDebug.lzs
M      WEB-INF/lps/lfc/debugger/platform/swf/LzDebug.as
M      WEB-INF/lps/lfc/debugger/platform/dhtml/LzDebug.js

Changeset: http://svn.openlaszlo.org/openlaszlo/patches/20070930- ptw-P.tar



Reply via email to