Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Bug with Extendscript Reflection object

Explorer ,
Dec 07, 2015 Dec 07, 2015

Hi everyone!

I think I found a bug in Extendscript.

As the docs says "any object has a reflect property.

So for example I wrote a function that returns array of strings that includes all the properties names of any object that are readonly:

function checkReadonlyValues(objToCheck) {

  var readOnlyArr = [];

  for (var i = 0; i < objToCheck.reflect.properties.length; i++) {

      if (objToCheck.reflect.properties.type === 'readonly') {

          readOnlyArr.push(objToCheck.reflect.properties.name);

      }

  }

  return readOnlyArr;

}

If I call the function and pass it an `AfterEffects FolderItem` it doesn't return that numItems is a readonly properties.

Also in debug the property numItems type is `readwrite`.

But as you know, `numItems` is a readOnly property.

I checked it in both CS6 and CC15(13.5).

Someone knows why is this happen? or how to avoid it(not a workaround solution)? or just to report a bug, and wait for fix?(where should I post this bug?)

TOPICS
Scripting
1.7K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 07, 2015 Dec 07, 2015

I had noticed this too and it is probably not a bug.

All properties of objects that belong to the After Effects Object Model seem to have type "readwrite", even though some can only be read.

An explanation can be (not sure)  that all properties are created with that type, and then are being watched (with Object.prototype.watch).

Then when you try to set a property that is not supposed to be set by you (us), the watch function will throw an error telling that it is readonly, while on the javascript level it is actually readwrite.

Note that the type of core javascript properties is correct. For instance:

var r = new RegExp("");

alert(r.reflect.find("source").type);    // alerts : "readonly" (the source of a regexp is readonly)

So if you want to know if a property is readonly, i think that the only way is to try to set the value:

function checkReadonlyValues(objToCheck) { 

    var readOnlyArr = [];

    var name;

    for (var i = 0; i < objToCheck.reflect.properties.length; i++) {

        name = objToCheck.reflect.properties.name;

        if (objToCheck.reflect.properties.type === "readonly"){

            readOnlyArr.push(name);

            }

        else{

            try{

                objToCheck[name] = objToCheck[name];

                }

            catch(e){

                readOnlyArr.push(name);

                };

            };

        };

    return readOnlyArr;

    };

checkReadonlyValues(app.project.activeItem)

The problem is that it creates a bunch of history entries, so you'd have to wrap the whole thing into an undoGroup and use app.executeCommand(app.findMenuCommendId("Undo")) at the end to clean things. Not very nice...

Xavier

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 07, 2015 Dec 07, 2015

Thanks Xavier!

I'm aware for this option to check if property is readonly or not but it's still seems to me as workaround.

If you will check you can see that not only the JavaScript cores  are right, but also File, and Folder etc. reflect object are right.

So it seems the problem is in After Effects(or maybe in other apps-I didn't check).

It looks like someone didn't do his job, because it's seems that every property type is readwrite(in the reflect object).

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 07, 2015 Dec 07, 2015

My answer was less about the workaround than the "explanation", although i'm not sure of it.

What i was trying to say is that as javascript properties, all properties in the AE Object Model are "writable", hence their type is "readwrite", it is no mistake, nobody failed, that's the way it is intended to work.

But agreed, it is confusing.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 07, 2015 Dec 07, 2015

Just checked in Illustrator:

If you check `app.reflect.find('buildNumber').type` is readonly.

In AfterEffects the same code above returns readwrite.

So why there is a difference between them?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 07, 2015 Dec 07, 2015

I don't know, as i only made an assumption about the after effects objects being watched.

So i'm not sure i should continue to answer, it would be nice if someone from the staff could clear this out.

But my bet is this ( ! )

i'd say that both teams have chosen different frameworks.

The ID team have defined readonly properties with "writable = false", while the AE team has defined everything with writable = true, but there is a watch function that can throw errors and prevent write access for properties that should not be written.

The ID way is less confusing, and the AE way more pedagogical (because of custom errors), at the cost of confusion for the nosy ones who inspect reflections...

Once again, that's only a bet.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 07, 2015 Dec 07, 2015

I meant Illustrator, not ID.

By the way, what happens if you try this in illustrator ? (i dont have it)

app.buildNumber = 456;

In AE this throws the error: After Effects error: Unable to set "buildNumber". It is a readOnly attribute.

I imagine that in Illustrator, it is silently ignored (like when you try to set the source property of a regexp), unless you use 'use strict', in which case you would get not a Illustrator error but a javascript error.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 07, 2015 Dec 07, 2015

I guess you are right..

In Illustrator unless you add `$.strict = true;` ExtendScript prints: 'Execution finished. Result: 456.

After you add `$.strict = true;` it's says: 'buildNumber is read only`(in try-catch it's throws a ReferenceError).

And in AE it always throws: 'After Effects Error: Unable to set "buildNumber". It is a readOnly attribute.' even if not in strict.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 07, 2015 Dec 07, 2015

Thank you for testing.

And thanks for telling how to use 'use strict'. I could never figure out how to do it.

Strange that it is a $ property. Does this means that it is global and cannot be set locally ??

Xavier.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 07, 2015 Dec 07, 2015

Glad to hear that I helped you!

It's only global but you can turn it on in the beginning of a function and turn it of at the end of the function.

Also there is an option to us `#strict on` but never tested so I don't know how it really works, but I guess it's works the same.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 07, 2015 Dec 07, 2015

Turn on/off... big turn off! And actually, from the Scripting Guide:

($ object, 'strict' property:)

When true, any attempt to write to a read-only property causes a runtime
error. Some objects do not permit the creation of new properties when
true.

So it isnt exaclty the same as 'use strict', in particular it doesnt inlcude the feature i was interested in: prevent the creation of variables without the keyword var.

Eg:

$strict=true;

var comp = app.project.activeItem;

var myLayer;

/*

*/

myLayr = comp.layer(1);

// no error: it just creates a new global variable called myLayr

Nevermind !

Xavier.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 07, 2015 Dec 07, 2015

Yes it's not the real use strict mode.

I assume it's because when ExtendScript was published, there wasn't use strict in the spec.

use strict was first released in EcmaScript 5(12/2009) and ExtendScript still relies on EcmaScript 3(12/1999).

I really hope that soon the ExtendScript team will decide to upgrade and change the ExtendScript engine to support the latest EcmaScript version, because there's a lot of programmers that writes non-short scripts, but longs.

I would be really happy to use some native EcmaScript 2015(and 2016 when released) features.

The decision not to upgrade, make it really hard to programmers (and artists that want to write some scripts) to write some scripts to Adobe programs. It's getting to hard to find some JavaScript code that is native JavaScript(EcmaScript 3).

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 09, 2015 Dec 09, 2015
LATEST
I really hope that soon the ExtendScript team will decide to upgrade and change the ExtendScript engine to support the latest EcmaScript version, because there's a lot of programmers that writes non-short scripts, but longs.

Don't hold your breath. Talks I've had with reliable sources, have leaned towards that not happening. Hence Character Animator being a standalone app, and the introduction of HTML5 (CEP) panels in AE. Both have access to the more recent ECMA features. Bridges, not fixes unfortunately.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines