Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

How to not put a function into a variable

Greetings.

I'm constantly getting the problem of being unable to distinguish whether the variable is going to be set to a value or to a function itself. Usually it takes me some time to try all the possible variants I could think of to find the solution, but this time I'm stuck.

I'm trying to build "doors" from each of 10 "roomN" passages to other within a (live:) macro. The problem is it's getting set to a (link-to: variable), not to a (link-to: value), no matter how I set it up. So after the macro stops, I have all doors leading to the 9th and 10th, because it's set to (link-to: $n), which is (link-to: "room9"). And I want them to be set to (link-to: "room1"), (link-to: "room2"), etc.

All (passage: "room")'s doors are set to (a:) beforehand.

(set: $index to 0)
(set: $roomam to 1)
(live: 10ms)[
(if: $roomam is 10)[(stop:)]
(if: $roomam is not 10)[
(set: $index to it + 1)
(set: $roomam to it + 1)
(set: $n to "room" + (text: $index))
(set: $m to "room" + (text: $roomam))
(set: $l to (link-goto: "$n"))
(set: (passage: $m)'s doors to it + (a: "$l"))
(set: (passage: $n)'s doors to it + (a: "(link-goto: $m)"))
]
]

There may be better ways to do so (I only want it to be done automatically, 'cause I want to add some random logic to door generation), so I would be glad to get any solution, or to be simply explained about the idea of how to set to a value or to a variable.

Thank you in advance!

Comments

  • warning: The ability to add custom properties to the Datamap returned by the (passage:) is considered a bug (issue 60) by Harlowe's developer, so while the technique works in version 1.2.2 of Harlowe it will not work in 2.x

    Your issue is caused by you referencing variables names within some of your String literals. eg
    (set: $l to (link-goto: "$n"))
    (set: (passage: $m)'s doors to it + (a: "$l"))
    (set: (passage: $n)'s doors to it + (a: "(link-goto: $m)"))
    
    ... this delays the evaluation of those variables ($n, $l and $m) until the point when they are actually added to the current page's output, at which time they will equal their current values. This will likely be values at the end of your loop.

    To fix this simple remove the double quotes on the first two and append the current value of the variable to the third. Note the usage of single quotes in the third.
    (set: $l to (link-goto: $n))
    (set: (passage: $m)'s doors to it + (a: $l))
    (set: (passage: $n)'s doors to it + (a: "(link-goto: '" + $m + "')"))
    
  • Finally was able to test the solution, the single quoted thing worked. And you saved me from starting a fun project on a bug (though I thought it was a cool possibility, but 2.x is much more important in perspective). Thank you one more time.

    Is there any in-depth info about these single quoted combinations? It's the second time you give me a solution with them and I want to understand why and how does it exactly work.
  • String is one of the data types supported by the different Story Formats and quotes (both single and double) are used to delimit a String literal / value. You can also combine Strings together using the plus symbol.
    (set: $var to "This is a String literal")
    
    (set: $result to "First String" + $var + "Second String")
    
    (link-goto: "This is a String value being passed as a parameter to the macro")
    

    In your example you are building a String value which consists of a macro call with a String parameter and you are doing that becauseyou want the delay the execution of the macro. The logical steps would be something like the following:
    a. The macro with a String parameter.
    
    (link-goto: "The String name of the passage")
    
    b. Convert step 1 into a String literal.
    
    "(link-goto: "The String name of the passage")"
    
    ... but step 2 would result in an error because we are trying to use the double quote to represent two things at the same time:

    1. the delimiter of String parameter
    2. the delimiter of the overall String literal.

    There are two ways to get around this mixed usage issue:
    a. Change one set of double quotes to single quotes.
    
    "(link-goto: 'The String name of the passage')"
    
    b. Use a backslash character to escape the internal double quotes.
    "(link-goto: \"The String name of the passage\")"
    

    Your example had a further complication which is you want to use the current value of the $m variable as the parameter of the delayed macro call, so you needed to concatenate the variable's current value to the other two parts of the overall String.
Sign In or Register to comment.