Copy link to clipboard
Copied
How do I override the toString() method in a class that lacks its own constructor?
(I'm actually working with the ManagedArticle class from Woodwing's SmartConnection plugin, but the probem appears to be general for any such class, so here we are with Page).
Example:
Page.prototype.toString = function() {
return "[object Page "+this.name+"]";
}
p0 = app.activeDocument.pages[0];
$.writeln("1: "+p0);
$.writeln("2: "+p0.toString());
$.writeln("3: "+Page.prototype.toString.call(p0));p1 = app.activeDocument.pages.add();
$.writeln("4: "+p1);
$.writeln("5: "+p1.toString());
$.writeln("6: "+Page.prototype.toString.call(p1));
produces:
1: [object Page]
2: [object Page]
3: [object Page 1]4: [object Page]
5: [object Page]
6: [object Page 2]
Is this a fool's errand? I'd really like easier debugging of this class and overriding the toString() would seem to be the way-to-go.
Thanks!
Copy link to clipboard
Copied
Can I ask why you would want to override a built in method?
It sounds like a silly thing to do in JavaScript...
Harbs
Copy link to clipboard
Copied
I add functions to prototypes all the time (File and Folder especially). I don't typically override, though.
Meanwhile, you can do stuff like that to the standard Extendscript objects - such as File, you can't do it for InDesign DOM objects.
Bob
Copy link to clipboard
Copied
You actually can do it to InDesign DOM objects (well some of them -- in certain ways anyhow). Here's a particularly interesting one:
var itemByLabel = function (label){
var labelIndex = null;
var labelArray = this.everyItem().label;
for(var i=0;i<labelArray.length;i++){
if(labelArray==label){labelIndex = i;break}
}
if(labelIndex===null){return null}
return this.item(labelIndex);
}
app.documents[0].pageItems;//needed to initialize the PageItems object
PageItems.prototype.itemByLabel = itemByLabel;
app.documents[0].paragraphStyles;//needed to initialize the ParagraphStyles object
ParagraphStyles.prototype.itemByLabel = itemByLabel;
etc...
I am very wary of prototyping anything but the simplest JS objects though...
You can do it with a regular function or method in a custom library (like Bob likes to do).
function CustomToString(object){
var string = object.toString();
string+="bla bla bla";
return string;
}
Harbs
Copy link to clipboard
Copied
Thanks, Harbs.
Huh. Well, that's good to know. I can add other methods but I can't override toString?
I don't suppose anyone knows why that is.
I guess for debugging I can set Page.prototype.d to my function and then call p0.d() for quick typing of debugging. Still not quite as nice, but less painful than other solutions...
Copy link to clipboard
Copied
My understanding here is kind of fuzzy, but I think you can more or less add methods safely, but don't try to modify methods provided by the C++ level of InDesign.
I generally limit my protoype functions to things like String and Array. I learned the hard way that prototyping Object is a bad idea...
Harbs
Copy link to clipboard
Copied
Well, I'm certainly not a Java/Javascript expert, but I thought that overriding toString() was The Java Way; ideally objects define an appropriate toString, but when they don't and simply inherit Object.toString(), it's there-to-be-overridden.
But more practically, when I am typing/debugging in the Javascript Console of the ESTK and examining a variable and it is one of these types, I'd like to be able to look inside it usefully without having to type in a long for loop to see the attributes. (This is where the analogy to the Page class breaks down, because it doesn't have terribbly interesting stuff to look into that requires for loops. But the ManagedArticle class has items, in particular entMetaData, that are much less easy to casually view).
How would you recommend this?
Copy link to clipboard
Copied
I thought that overriding toString() was The Java Way
Indeed, now I remember. Josh Bloch's Effective Java: Item 10: Always override toString()
(p.51). I guess that's about as authoritative as you can get for Java, but I'll just remain doomed to suffer
😉
That's life.
Copy link to clipboard
Copied
Java and JavaScript have nothing at all to do with each other...
Harbs