spacer spacer spacer

2005-08-27

Fourth and Bitz

Well, after beating on ASSetPropFlags for sometime, I finally came to the conclusion that the flag table that everyone has been referencing is wrong

BLITZ Labs » Blog Archive » ASSetPropFlags - The correct flag table

Well, there must be something else missing from all the tables on the web: the real meaning of that fourth argument. Is it really just a boolean? If it is just a boolean, then setting the flags to 0 should make a property writable and deletable too. Clearly that is not the case:

lzx> foo.test = 'bar' 
"bar" 
lzx> ASSetPropFlags(foo, null, 6) 
lzx> delete foo.test 
false 
lzx> ASSetPropFlags(foo, null, 0, true) 
lzx> delete foo.test 
false

It’s pretty clear to me that the fourth argument is also a bitmask, and it is the mask of the bits to clear (before you set the bits in the third argument). That is why so many people are confused. If you pass true as the fourth argument, it is coerced to a number, 1, so only the enumerability bit is cleared. Here’s the proof:

lzx> ASSetPropFlags(foo, null, 0, 2) 
lzx> delete foo.test 
true
Comments

This is great, I’ve not heard ANYONE talk about the 4th argument, hence why I didn’t talk about it either.

I’m not totally clear on what you’re saying here, though, but I have a feeling that it’s probably related to some of the bugs I’ve seen in the past. Now, I’m wondering if it’s not a bug ;)

Do you think you could expand on that explanation with a few more samples etc?

Thanks for all this! - John

2005-08-29 00:02 | John Grden

Ok, well, I went an ran a test based on what you posted here and I’m not getting the same results. The results I’m seeing are consistent with the bit flags in the 3rd argument, but it seems that the 4th isn’t doing what I thought you were saying it would do.

here’s the code I used, based on your sample above:

var foo;
resetFoo();
trace(foo.test); //bar

ASSetPropFlags(foo, null, 6)
delete foo.test
trace(foo.test); // bar/not deleted

resetFoo();
ASSetPropFlags(foo, null, 0, true)
delete foo.test
trace(foo.test); // false/undefined/deleted

resetFoo();
ASSetPropFlags(foo, null, 0, 2)
delete foo.test
trace(foo.test); // false/undefined/deleted

function resetFoo()
{
    this.foo = new Object();
    this.foo.test = 'bar'
}

So, I’m guessing that I’ve completely missed what you were saying altogether since it’s acting the way I’ve known it to ;(

Sorry to be a pest, but I really need to nail this down ;)

Thanks for your help! - John

2005-08-30 09:28 | John Grden

John, your test is fooling you. Since you are creating a new foo object each time you call resetFoo, your ASSetPropFlags are not carrying over from one test to the next. Here’s a more extensive example, which I hope illustrates the point (this is done using the OpenLaszlo debugger, which lets you interactively evaluate Javascript on the Flash player:

lzx> var foo = new Object 
lzx> foo 
«Object#37| {}» 
lzx> foo.test='bar' 
"bar" 
lzx> ASSetPropFlags(foo, null, 6) 
lzx> delete foo.test 
false 
lzx> foo.test 
"bar" 
lzx> ASSetPropFlags(foo, null, 0, true) 
lzx> delete foo.test 
false 
lzx> foo.test 
"bar" 
lzx> ASSetPropFlags(foo, null, 0, 2) 
lzx> delete foo.test 
true 
lzx> foo.test 
WARNING: interactive-eval-14: reference to undefined property 'test' 
lzx>
2005-08-30 09:59 | ptw

Ok, I wondered if that’s what you were doing ;)

Yes, if I don’t reset the object, I get the same results in the test.

So my question really is what values can we use for the 4th argument and why?

I’ve not ever heard of using ASSetPropFlags multiple times on an object like this, but I like where it’s going ;)

I’d like to put a usage pattern together and “best practices”. Right now, I’m at a lose as to why I would use 6, then 0 (with true), then 0 with (2).

can you expand on the why’s and whatfors?

again, excellent work on this, really appreciate your time and help - John

2005-08-30 13:05 | John Grden

You would want to use ASSetPropFlags more than once if you want to turn the flags on and off. The second arg is the flags to turn off, the first arg is the flags to turn on. I hope this example clears that up:

lzx> var foo = { secretProp: 'secret', publicProp: 'public' } 
lzx> foo 
«Object#41| {secretProp: secret, publicProp: public}» 
lzx> ASSetPropFlags(foo, 'secretProp', 1) 
lzx> foo 
«Object#41| {publicProp: public}» 
lzx> ASSetPropFlags(foo, 'secretProp', 0, 1) 
lzx> foo 
«Object#41| {secretProp: secret, publicProp: public}» 
lzx>

So, by turning on the Don't Enumerate flag for secretProp it doesn’t show up. Turning it off makes it show up again.

2005-08-30 14:30 | ptw

Ok, I took your code and used it just to play around with the flags (I use Xray, hence tt() ;):

var foo = { secretProp: ‘secret’, publicProp: ‘public’ } tt(“foo”, foo); ASSetPropFlags(foo, ‘secretProp’, 1) tt(“foo”, foo); ASSetPropFlags(foo, ‘secretProp’, 0, 1) tt(“foo”, foo);

which traces: (73) foo: secretProp = secret publicProp = public

(85) foo: publicProp = public

(86) foo: secretProp = secret publicProp = public

if I changed the last ASSetPropFlags call to: ASSetPropFlags(foo, ‘secretProp’, 0, 0)

Sure enough, the secretProp is NOT enumerable, and now I start to see what you’re saying.

Previously, I’d have said, that if you use 0 in the 3rd argument, you should be able to enumerate all - regardless of the 4th argument. But it never failed for me since I always set the 4th flag to true.

So, yeah, now it makes sense. I guess I struggle to see a situation where you’d be using ASSetPropFlags and not want to see the hidden properties. Otherwise, why would you be running it in the first place? Isn’t that the reason for using it in the first place?\

Then again, I’m looking at its use purely through a debug POV.

Thanks again for your patience and time, really do appreciate it.

just for the record, the 4th argument is either true/false (1/0) - is that right? Why did you use a 2 in one of your examples?

2005-09-01 22:08 | John Grden

I don’t know how to be any clearer: The 4th argument is a bitmask, just like the 3rd argument. The 3rd argument specifies flags to set, the 4th argument specifies flags to clear. I used the Number 2 (bit 1, binary 010, Don't Delete) to show manipulating a flag other than Don't Enumerate (bit 0, binary 001, or 1 as a Number, which happens to also be true as a Boolean). You have to use your own imagination as to why you might want to set or clear particular flags.

2005-09-02 08:01 | ptw

Post a comment

Thanks for signing in, . Now you can comment. (sign out)

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)


Remember me?


You are not signed in. You need to be registered to comment on this site. Sign in