Hey,
I'm using the latest SugarCube 2 and Twine 2 versions.
I ran into a read-only error when passing my object from SugarCube to JavaScript and try to write it's property.
Here's what I did:
Start Passage:
<<set $mydir = {
"mydirectory" : "Get info from JavaScript and store current work directory here."
}>>>
<<findcwd $mydir>>
JavaScript:
macro.findcwd = {
handler : function (place, macroName, params, parser) {
var mydir = params[0];
// I snagged this from stackoverflow to get the cwd
var loc = window.location.pathname;
var dir = loc.substring(0, loc.lastIndexOf('/'));
// Twine starts to complain here about
// "mydirectory of "Get info from JavaScript and store current work directory here.""
// being a read-only property
mydir.mydirectory = dir;
}
}
So, what did I want to accomplish? I wanted to code a work around for my project to detect whether I am in development or published mode and specify where my GIF and JPG files are located accordingly, so Twine can find them when I'm using relative paths in HTML.
I've sort of accomplished this since I could get access the cwd and do my checks. Then I wondered if I could pass SugarCube2 objects per reference and whether I could store the gained information in a property (member).
Now, unfortunately this fails. It appears that SugarCube creates read-only properties for its objects.
Then I tried something like "mynumber" : 1 and increment it in JavaScript. That for some reason worked.
After that I tried adding writable : true to $mydir in SugarCube but the code still failed to write the property of the object.
I finally found a way to write the value in JavaScript by invoking a SugarCube macro:
new Wikifier(place, "CWD is indeed: <<set $mydir.mydirectory is \"" + dir + "\">>
I remember escaping a couple of quotations. But the code worked.
This begs the question:
What is going on? How, can I set my object property inside a macro without telling SugarCube to do it? Why does this work on numbers but fails on strings? Do I need to dig through SugarCube's macro implementation when problems like these occur?
Thank you for your explanation and help in advance
Br,
Disane
Comments
As far as your object being read-only. No. SugarCube does not modify the property descriptors of your objects at all. If you actually saw an error to that effect, you obtained it doing something incorrectly—what that was, I haven't the foggiest.
That you're trying to do this as a macro at all is odd. There's no need for that as far as I've understood your explanation. You could simply run the code once at start up. /shrug
Regardless. Here are correct versions of what you were trying to do. Both will return an error if you pass them anything other than an object.
If you intend to use the legacy Twine 1 vanilla story format macro API, then you need to spell it correctly—it's macros not macro. For example:
Or the same using SugarCube v2's native macro API:
I see you like defensive programming and like to check what is actually passed through the arguments. I really like that. Too bad, I only started out with JS not a long time ago, but I'll pick it up fast. Regardless, It's nice to see good code practices.
About running the code once: Yeah, true. There's no need for a macro in that case. I was merely experimenting. What would you say would be the best area to put this kind of code in? Right inside the start passage?
About SugarCube 1.x and 2.x: Thanks, I took the code from a guy who made tutorials on YouTube (VegetarianZombie) from 2015. He was using Sugarcube 1.x indeed. I guess, I was using the legacy code in SugarCube 2.0, which could also be a cause of the problem. To be honest the documentation for SugarCube is just too dry for me and not enough for a beginner to start working on anything in my opinion. I had real issues figuring out what macros and passages were (and what they were made for), until I saw them in action in Zombie's videos. Now, the documentation is starting to make sense.
The error does actually happen and reading your answer, I assume it must be my "user error" interfering. It will be a treat to find out why it was thrown at me. I'll let you know once I figured it out.
Anyways, thank you for the help!