Is layers = app.activeDocument.layers static?

I’m testing out some code to create and add a text layer, to select individual layers exclusively and additively, etc, like so:

	let layers = app.activeDocument.layers;
	//select the lowest layer exclusively
	await utls.selectLayerByID(layers[layers.length - 1].id, true);
	let layerID = await utls.createTextLayer(textLayerName, textLayerContents);
	//select the top two layers to ensure that selection doesn't affect setLayerColor, setLayerAllLocked, and setLayerVisible
	await utls.selectLayerByID(layers[0].id, true);
	await utls.selectLayerByID(layers[1].id, false);

If I start with only one layer, layers.length equals 1. After adding the text layer in utls.createTextLayer, layers.length is still 1 and the last line crashes. But if I update layers after the call to utls.createTextLayer like so:

	let layers = app.activeDocument.layers;
	//select the lowest layer exclusively
	await utls.selectLayerByID(layers[layers.length - 1].id, true);
	let layerID = await utls.createTextLayer(textLayerName, textLayerContents);
	layers = app.activeDocument.layers;
	//select the top two layers to ensure that selection doesn't affect setLayerColor, setLayerAllLocked, and setLayerVisible
	await utls.selectLayerByID(layers[0].id, true);
	await utls.selectLayerByID(layers[1].id, false);

layers.length equals 2 and there’s no problem. That appears to mean that “layers” is a static copy of the layers list???

I’ve pointed Adobe folks to this :point_up_2:t2:

BTW, I tried with JSX and it works differently—that is, it works as you’d expect :wink:

var ll = app.activeDocument.layers;
$.writeln(ll.length); // 1
app.activeDocument.artLayers.add();
$.writeln(ll.length); // 2

Not that it probably matters, but I like “layers” being static. I can always programmatically update it when/if I want it updated w/o having to save off the previous version.

I assume changing that now might break lots of plugins. It should stay as is or should be very well communicated to all devs, in what Adobe isn’t good at at all

In my mind there’s an implicit understanding that you’re getting a pointer to an object. A static copy is inconsistent with common practices. And as Davide pointed out, “it works as you’d expect” in JSX, so there’s a serious inconsistency between the two platforms. But whichever way it goes, the documentation should make it clear. Though I’m beginning to understand that documentation is an afterthought at Adobe.

And as an afterthought of my own, it’s unlikely that it’ll break as many plugins as you might think. In the second code block I posted, it would simply mean that there’s an extraneous update of the “layers” variable that’s no longer needed.

What defines if it’s needed or not? What if I want to have the initial state of layers no matter what actions I perform on them? I totally get your point and maybe that’s not expected in JS - I don’t know. I’m a PHP developer by occupation and if not this post, I wouldn’t expect it to be a pointer :man_shrugging: So I believe there might be quite a few plugins that currently assign layers to a variable like this and I wouldn’t dare to guess how many of them rely for that variable to not change when modifying actual layers :thinking:

@Karmalakas good point.

backward compatibility aside, it’s always better to stick with standards and expectations.
we can always use Object.assign() for creating a (static copy/value instead of reference) however I doubt it will be changed at this point

Exactly. I don’t disagree, that it should be as most would expect, but what I’m saying, it would be pretty bad to change now, when nobody has a clue how much this is already used as it is

@Karmalakas hard agree; but if the decision is taken to make such a change then it categorically needs to be communicated beforehand.

Hence my other option, which IMO is quite unrealistic