Harlowe 3.1: stupid problem with for: macro

Hi, all !

This code, which should print an inventory in the sidebar, doesn’t work:

(set: _N to $Inv’s length)
(set: _St to “”)
(if: _N > 0)[
(append:?Sidebar)[Vous avez :]
(for: each _St, …$Inv)[(append: ?Sidebar)[_St]]
]
I get the error message “This lambda has two variables named ‘St’.”
Removind “(set:_St to “”)” doesn’t work either.

I’m a newbie with Harlowe,sorry. Can you help me ?
Thanks in advance.

P.S: I use Twine 2.3.5 and Harlowe 3.1.0.

note: I don’t know if this was a result of the cut-n-paste process but I noticed that your example included the invalid usage of both

  1. topographical (curly) single and double quotes ( “” and ’), instead of the standard " and ’ characters found on the keyboard.
  2. the … character, instead of three consecutive full stops …

You didn’t supply an example of the contents of your $Inv story variable, so I will assume that it is an Array of String literals like the following…

(set: $Inv to (a: "Apple", "Orange", "Pear"))

The following code should product the same output as your own example…

(if: $Inv's length > 0)[
	(append: ?Sidebar)[Vous avez :]
	(for: each _item, ...$Inv)[(append: ?Sidebar)[_item]]
]

…I renamed the temporary variable to make it more clear what it represents. You may want to add some sort of separator (eg. white-space, coma, etc…) between each of the ‘items’ you are adding the the ‘Sidebar’.

warning: The default width of the area containing the ‘Sidebar’ contents is set to being just wide enough to display the Undo and Redo links, which will likely cause your own content to wrap in unexpected ways. While you can add custom content to this area it default layout isn’t designed for such, you may want to look at the two Harlowe based “Left Sidebar” related recipes in the Twine Cookbook for ideas on how to overcome this issue.
“Left Sidebar”: Harlowe (both v1.x and v2.x series)
“Left Sidebar”: Harlowe (only v2.1.0 or later)

note: both of the above recipes also work for the 3.x series of Harlowe, their labels & descriptions just haven’t been updated to indicate this.

1 Like

Thanks for your help, Greyelf.

It works. But this doesn’t work:

(set: $InvLength to 2)
(set: $Inv to (dm: “Sword01”, “Votre épée”,“Axe01”,“Votre hache”))

(if: $InvLength > 0)[
(append: ?Sidebar)[
Vous avez :
]
(for: each _item, …$Inv)[(append: ?Sidebar)[- _item
]]
]

I get this error message : “There isn’t a temp variable named _item in this place.” ???

But i’d like to get “Votre épée”, then “Votre hache”.

1 Like

notes: Your latest example includes the same invalid characters as your previous one, if they are in your actual project then you need to replace them as I indicated. It would also help if you use the Preformatted Text option (in the toolbar) when supplying code examples, it makes them easier to read and to copy-n-paste.

There are a number of issues with your latest example:

1: Your usage of invalid topographical (curly) double quotes is one of the reasons you are seeing that error.

2: The spread operator (three consecutive full stops) only works with an Array.

If you want to use the (for:) macro with a Datamap object then you first need to use the (datanames: ) macro to obtain an Array containing the names / keys of each of the key/value pairs within that object. You can then use the (for:) macro to loop through each of those keys.

3: You are hard-wiring the value of the $InvLength variable instead of interrogating the contents of the $Inv variable to determine how many ‘items’ it actually contains.

A variation of your example that incorporates the above information, and which also uses HTML
elements
to inject line-breaks as needed.

(set: $Inv to (dm: "Sword01", "Votre épée", "Axe01", "Votre hache"))

(set: _names to (datanames: $Inv))
(if: _names's length > 0)[
(append: ?Sidebar)[<br>Vous avez :]
(for: each _name, ..._names)[
	(append: ?Sidebar)[<br>- (print: $Inv's (_name))]]
]
1 Like

Many thanks, Greyelf. This part of the manual (“data structure”) has always been rather obscure for me.

1 Like

Yes, I think that implementing an inventory or a diary would be a good candidate for the cookbook: it’s something that people often want to do, and it explains a tool that’s both tricky to understand and also very useful.

The issue is that an “inventory” can mean different things to different people.

And implementation can range from something as simple as an Array that contains the (String) name of “items”…

(set: $inventory to (a:))
(set: $inventory to it + (a: "Apple"))
(set: $inventory to it - (a: "Apple"))
or
<<set $inventory to []>>
<<run $inventory.push("Apple")>>
<<run $inventory.delete("Apple")>>

… to something as complex as HiEv’s Universal Inventory System (UInv). With implementations like ChapelR’s The Simple Inventory System sitting somewhere in between.

The array example in the cookbook uses a basic inventory as its use-case, so an inventory is technically covered.