Howdy, Stranger!

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

Possible bug with vars inside array in Harlowe?

I'll show the code first:
(set: $hammer to (datamap:
		"Name", "Hammer",
		"Description", "Yeah, it's a hammer.",
		"slot", "right_hand"
	)
)
(set: $weapons to (array: $hammer,$hammer,$hammer))

(live: 1s)[
Name 1: (if:$weapons.length > 0)[(print: $weapons's 1st's Name)](else:)[I'm empty]
Name 2: (if:$weapons.length > 1)[(print: $weapons's 2nd's Name)](else:)[I'm empty]
Name 3: (if:$weapons.length > 2)[(print: $weapons's 3rd's Name)](else:)[I'm empty]

(link-reveal: "Discard 2nd hammer?")[(set: $weapons to it - (a:$weapons's 2nd))]
]
It creates a $hammer var, and a $weapons with two "hammers" inside. The problem is: if I want to discard only one hammer, with the given link-reveal, it discards all of them.

Wasn't it supposed to only remove the second $hammer from the array instead of removing the var itself and rendering empty other positions?

Thank you.

Comments

  • As solution (or fix), I'm moving on of those "hammers" to a trash bin array:
    (set: $i_trash to (datamap:"Name", "trash"))
    
    Then:
    (link-reveal: "Discard 2nd hammer")[(move: $weapons's 2nd into $i_trash)]
    
  • l3m35 wrote: »
    (set: $weapons to (array: $hammer,$hammer,$hammer))
    
    Your basic problem is that you're adding a reference to the exact same hammer map to the array three times.

    The result is that when you do the following:
    (set: $weapons to it - (a:$weapons's 2nd))
    
    What you're saying is: remove the element(s) from the $weapons array which match the second element within the array. Since all three elements reference the same map, they all match and thus are all removed.

    If you want the hammers to be unique within the array, you need to add them that way. For example:
    (set: $weapons to (array:
    	(datamap:) + $hammer,
    	(datamap:) + $hammer,
    	(datamap:) + $hammer
    ))
    
    That creates three unique copies of the $hammer map and adds them to the array.

    From the Harlowe Array type documentation: (pay special attention to the second sentence)
    Additionally, you can subtract items from arrays (that is, create a copy of an array with certain values removed) using the - operator: (a:"B","C") - (a:"B") produces (a:"C"). Note that multiple copies of a value in an array will all be removed by doing this: (a:"B","B","B","C") - (a:"B") also produces (a:"C").
  • Since I'm not a pro programmer, I thought on:
    (set: $weapons to it - (a:$weapons's 2nd))
    
    ...as something like: "let's empty the 2nd position" and not "please exclude what is stored at the 2nd position", know what I mean? I have some experience with PHP, but never tried something similar to see what happens.

    But I'll try the way you suggested. Thank you.
  • edited September 2016
    l3m35 wrote: »
    Since I'm not a pro programmer, I thought on:
    (set: $weapons to it - (a:$weapons's 2nd))
    
    ...as something like: "let's empty the 2nd position" and not "please exclude what is stored at the 2nd position", know what I mean?
    Well, as I noted above, that particular bit of behavior is clearly spelled out within its documentation.

    As to not being a "pro programmer". That probably wouldn't have helped you much as much as you might hope it would, as that particular behavior is fairly unique to Harlowe. In most systems, the very idea of subtracting one array from another to remove elements is complete and utter nonsense.

    Also, just to be clear, I'm not a Harlowe expert. There may be a native (i.e. Harlowe/non-JavaScript) way to remove a particular index and associated value from an array that I simply do not know about. If there is, then that might be better to use that in this instance.

    Either way, in most cases, you probably should be adding unique copies of items to the array—as I outlined in my first post—which should allow you to use array subtraction without issue.
  • TME is correct, it is better to add unique copies of items to the array that way the array arithmetic will only remove the indicated element(s).

    As demonstrated in the Harlowe Manual you can also use the (move:) macro to remove an element from an array.
    (move: $weapons's 1st into $dummy)
    
Sign In or Register to comment.