Assigning Objects by Reference
In Pine Script™, objects are assigned by reference. When you assign an existing object to a new variable, both variables point to the same object instance. Consequently, modifications made through either variable will reflect in the object they both reference.
Example: Reference Assignment
//@version=5 indicator("") type pivotMarker int positionX float positionY marker1 = pivotMarker.new() marker1.positionX := 1000 marker2 = marker1 marker2.positionX := 2000 // Both plots will display 2000. plot(marker1.positionX) plot(marker2.positionX)
In this example, marker2
is assigned the reference of marker1
. Changing positionX
in marker2
also changes positionX
in marker1
.
Creating Independent Copies with copy()
To create an independent copy of an object, use the built-in copy()
method. This method generates a new object instance that initially shares the same field values as the original but is otherwise separate.
Example: Independent Copy
//@version=5 indicator("") type pivotMarker int positionX float positionY marker1 = pivotMarker.new() marker1.positionX := 1000 marker2 = pivotMarker.copy(marker1) marker2.positionX := 2000 // marker1 plots 1000 and marker2 plots 2000. plot(marker1.positionX) plot(marker2.positionX)
In this script, marker2
is an independent copy of marker1
. Changing marker2.positionX
does not affect marker1
.
Shallow vs Deep Copy
- Shallow Copy: The
copy()
method performs a shallow copy. If the object includes fields with special types (like arrays or labels), those fields in the copied object still point to the same instances as in the original object. - Deep Copy: To create a deep copy where all fields are independent, including special types, you need to explicitly copy these fields.
Example: Deep Copy
//@version=5 indicator("Deep Copy") type InfoMarker string info label lbl method deepCopy(InfoMarker this) => InfoMarker.new(this.info, this.lbl.copy()) var parentMarker = InfoMarker.new("", label.new(0, 0)) var deepMarker = parentMarker.deepCopy() // Updating parent and deep markers independently parentMarker.lbl.set_text("Parent") deepMarker.lbl.set_text("Deep Copy")
In this example, deepMarker
is a deep copy of parentMarker
, including an independent copy of the lbl
field. Changes made to deepMarker.lbl
do not affect parentMarker
.
Conclusion and Key Takeaways
- Reference Assignment: Default object assignment in Pine Script is by reference, leading to shared object instances.
- Independent Copies: Use the
copy()
method for shallow copies or define a custom method for deep copies when you need independent object instances. - Shallow vs Deep Copy: Understanding the distinction between shallow and deep copies is crucial when working with complex objects containing special type fields.