//Understanding assignment by value
//this is a very basic topic, but there are
often
//misunderstandings because of behaviour.
//__________In sc everything is passed by
value.
a = 0;
b = a;
[a, b, a === b].postln;
a = 1;
[a, b, a === b].postln;
in order to achieve a different behaviour, reference can be used.
a reference is a very simple object (Ref)
that has one instance variable,
value. a shortcut is often used which is the `-character,
as seen in Sequencer.kr(`[1, 2, 3],
Impulse.kr(2))
//___________use Ref just like Plug or ControlValue
(SC3)
a = Ref(0); //a
now contains a reference to the number zero
b = a; // a and b now refer to the same
object
[a, b, a === b].postln;
a.set(8.0); //change the value of a's reference
[a, b, a === b].postln; // also b has changed.
//__________similarly, an array can be used:
a = [0]; //a now refers to an
array containing the number zero
b = a; // a and b now refer to the same
object, the array.
[a, b, a === b].postln;
a.put(0, 8.0); //change the value in the array
that a contains
[a, b, a === b].postln; // a and b still refer
to the same object
//_________note: when the array size is exeeded,
a new array gets created.
a.add(2.0);
[a, b, a === b].postln; // nothing has happened
a = a.add(2.0);
[a, b, a === b].postln; // b still is refering
to the old array that was used to create the new
//content of
a. a List can be used to avoid this.
//_________this is actually the case for any
instance variable.
a = Date.getDate; //create a new instance of Date and store it in a
b = a; // a and b now refer to
the same object, a date.
[a.year, b.year].postln;
a.year = 1792; //set the instance variable
of Date (that is contained in a), equivalent to "a.year_(1792);"
[a.year, b.year].postln; //a and b still refer
to the same object.
//__________note: also here there is cases
where this is not true.
a = Rect.newBy(0, 0, 20, 20);
b = a;
[a.top, b.top].postln;
a = a.moveTo(50, 50);
[a.top, b.top].postln;
//to understand this, one has to have a look
at the method moveTo in Rect:
moveTo { arg h, v;
^Rect.new(h, v, right -
left + h, bottom - top + v)//and see that
a new rectangle is created.
}
//if it was like the following, it wouldn't
show this behaviour
moveTo { arg h, v;
right = right - left + h;
bottom = bottom - top + v;
}
//it does work with the method setExtent:
a = Rect.newBy(0, 0, 20, 20);
b = a;
[a.width, b.width].postln;
a.setExtent(50, 50);
[a.width, b.width].postln;
//because setExtent doesn't create a new rectangle
setExtent { arg width=0, height=0;
right = left + width;
bottom = top + height;
}