Howdy, Stranger!

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

Fun with Datasets pt. 2 (Harlowe)

Okay, why does this:
(set: $data to (a:1,2,3))
(set: $set to (dataset:))

(set:$set to it + (dataset:$data))
(print:$set's length)
(set:$set to it + (dataset:$data))
(print:$set's length)

(set: $choice to $data)
(set:$set to it + (dataset:$choice))
(print:$set's length)
(set:$set to it + (dataset:$choice))
(print:$set's length)

(set: $choice to $data)
(set:$set to it + (dataset:$choice))
(print:$set's length)
output this?
1
1

2
2

3

Datasets shouldn't be able to hold duplicates, so why doesn't Harlowe treat a variable holding something already inside the dataset, or even the same variable already in the dataset (after being set again) as duplicates?

Sorry for the larger than necessary amount of prints; I just wanted to clearly illustrate what does and doesn't get added to a dataset. Notable also is that if $data is a string, number, or boolean, it works no problem, but I have to use datasets containing arrays. :/

Comments

  • Welcome to the wonderful world of Harlowe variables, objects, copies, deep copies, passage state, and why using objects in Twine stories is not for the faint hearted. Some of these issues also relate to other Story Formats.

    When you add items to a collection object like an Array (Datamap, Dataset) the result is a new object, and this causes an interesting side effect if the original object was referenced by more that one variable. The variable used in the modification will reference the new object where as the other variables will still reference the original object.
    {(set: $data to (a:1,2,3))
    (set: $choice to $data)
    
    }data: (print: $data)
    choice: (print: $choice)
    
    Add an element to data:
    {(set: $data to it + (a:4))
    }data: (print: $data)
    choice: (print: $choice)
    

    It is even more complex when you modify the contents of an element within a collection object, especially if the element is a collection object itself.
    {(set: $data to (a:1,2,3))
    (set: $list to (a: $data, $data))
    }data: (print: $data)
    list e1: (print: $list's 1st)
    list e2: (print: $list's 2nd)
    
    Change the value of second element of data, the other two update because still same object:
    {(set: $data's 2nd to 4)
    }data: (print: $data)
    list e1: (print: $list's 1st)
    list e2: (print: $list's 2nd)
    
    But update the same element again and discover that data and the two elements are no longer the same object after the first change.
    {(set: $data's 2nd to 5)
    }data: (print: $data)
    list e1: (print: $list's 1st)
    list e2: (print: $list's 2nd)
    
    But at lease the two elements in the list are still the same object, so you can update one and effect the other. 
    {(set: $list's 1st's 2nd to 6)
    }data: (print: $data)
    list e1: (print: $list's 1st)
    list e2: (print: $list's 2nd)
    
    Opps but that resulted in the two elements now referencing different objects, which you will see if you update the same element again.
    (set: $list's 1st's 2nd to 7)
    data: (print: $data)
    list e1: (print: $list's 1st)
    list e2: (print: $list's 2nd)
    

    I have left the best till last, when the reader navigates from one passage to another the current state of all known variables is copied and it is this copy that is made available to the new passage. This means that all variables that referenced objects now reference new instances of those objects with a similar value, including any objects that those original objects referenced internally.

    eg. the $data variable references a new Array object, $list references a new Array object, each element of $list references a new Array object, etc....
  • Oh my...
Sign In or Register to comment.