digitalmars.D.learn - Can someone explain why i can change this immutable variable please?
- Gary Willoughby (27/27) Oct 09 2013 Can someone explain why i can change Bar's immutable name member
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (12/38) Oct 09 2013 Foo.Change receives a string:
- Gary Willoughby (25/72) Oct 09 2013 So why does this give me an error i expect:
- Dicebot (4/4) Oct 09 2013 D does stripping of qualifiers from top level when creating a
- Daniel Davidson (19/43) Oct 09 2013 Maybe this will help explain it:
- Gary Willoughby (3/20) Oct 09 2013 Ah right, of course. Thanks.
- Daniel Davidson (10/15) Oct 09 2013 And to prove it - change main to:
- Orvid King (7/34) Oct 09 2013 This would fail if you were to declare `change` as `void
Can someone explain why i can change Bar's immutable name member please? import std.stdio; class Foo { public void change(string name) { name = "tess"; writeln(name); } } class Bar { private static immutable string name = "gary"; public void test() { auto foo = new Foo(); foo.change(this.name); } } void main(string[] args) { auto bar = new Bar(); bar.test(); } I thought an error would inform me that the `Foo.change` function is being called with the wrong parameter type.
Oct 09 2013
On 10/09/2013 08:26 AM, Gary Willoughby wrote:Can someone explain why i can change Bar's immutable name member please? import std.stdio; class Foo { public void change(string name) { name = "tess"; writeln(name); } } class Bar { private static immutable string name = "gary"; public void test() { auto foo = new Foo(); foo.change(this.name); } } void main(string[] args) { auto bar = new Bar(); bar.test(); } I thought an error would inform me that the `Foo.change` function is being called with the wrong parameter type.Foo.Change receives a string: public void change(string name) { name = "tess"; writeln(name); } That string is independent from the argument (i.e. Bar.name). They initially share the same characters. Either of those strings can leave this sharing at will, and that is exactly what name="tess" does. 'name' now refers to different immutable chars. Ali
Oct 09 2013
On Wednesday, 9 October 2013 at 15:33:23 UTC, Ali Çehreli wrote:On 10/09/2013 08:26 AM, Gary Willoughby wrote:So why does this give me an error i expect: import std.stdio; class Foo { public void change(string[] name) { name[0] = "tess"; writeln(name); } } class Bar { private static immutable string name[] = ["gary"]; public void test() { auto foo = new Foo(); foo.change(this.name); } } void main(string[] args) { auto bar = new Bar(); bar.test(); }Can someone explain why i can change Bar's immutable name member please? import std.stdio; class Foo { public void change(string name) { name = "tess"; writeln(name); } } class Bar { private static immutable string name = "gary"; public void test() { auto foo = new Foo(); foo.change(this.name); } } void main(string[] args) { auto bar = new Bar(); bar.test(); } I thought an error would inform me that the `Foo.change` function is being called with the wrong parameter type.Foo.Change receives a string: public void change(string name) { name = "tess"; writeln(name); } That string is independent from the argument (i.e. Bar.name). They initially share the same characters. Either of those strings can leave this sharing at will, and that is exactly what name="tess" does. 'name' now refers to different immutable chars. Ali
Oct 09 2013
D does stripping of qualifiers from top level when creating a copy which allows to pass immutable stuff as mutable parameter by value. Adding any single level of immutable indirection will make this impossible and result in compile-time error.
Oct 09 2013
On Wednesday, 9 October 2013 at 15:46:29 UTC, Gary Willoughby wrote:So why does this give me an error i expect: import std.stdio; class Foo { public void change(string[] name) { name[0] = "tess"; writeln(name); } } class Bar { private static immutable string name[] = ["gary"]; public void test() { auto foo = new Foo(); foo.change(this.name); } } void main(string[] args) { auto bar = new Bar(); bar.test(); }Maybe this will help explain it: void main() { pragma(msg, typeof(Bar.name)); pragma(msg, typeof(Foo.change)); } will print: immutable(char[][]) void(string[] name) The latter is really: void(immutable(char)[] name) The former is really: immutable(immutable(immutable(char)[])[]) So for name the whole kit and kaboodle is immutable and you can not pass the whole immutable thing into something that is only immutable at one level. Thanks Dan
Oct 09 2013
On Wednesday, 9 October 2013 at 16:02:43 UTC, Daniel Davidson wrote:Maybe this will help explain it: void main() { pragma(msg, typeof(Bar.name)); pragma(msg, typeof(Foo.change)); } will print: immutable(char[][]) void(string[] name) The latter is really: void(immutable(char)[] name) The former is really: immutable(immutable(immutable(char)[])[]) So for name the whole kit and kaboodle is immutable and you can not pass the whole immutable thing into something that is only immutable at one level. Thanks DanAh right, of course. Thanks.
Oct 09 2013
On Wednesday, 9 October 2013 at 15:33:23 UTC, Ali Çehreli wrote:That string is independent from the argument (i.e. Bar.name). They initially share the same characters. Either of those strings can leave this sharing at will, and that is exactly what name="tess" does. 'name' now refers to different immutable chars.And to prove it - change main to: void main(string[] args) { auto bar = new Bar(); bar.test(); writeln(Bar.name); } and as much as you may want to become tess, you will still be gary.
Oct 09 2013
On Wednesday, 9 October 2013 at 15:26:35 UTC, Gary Willoughby wrote:Can someone explain why i can change Bar's immutable name member please? import std.stdio; class Foo { public void change(string name) { name = "tess"; writeln(name); } } class Bar { private static immutable string name = "gary"; public void test() { auto foo = new Foo(); foo.change(this.name); } } void main(string[] args) { auto bar = new Bar(); bar.test(); } I thought an error would inform me that the `Foo.change` function is being called with the wrong parameter type.This would fail if you were to declare `change` as `void change(ref string name)`. This is valid because you are passing the value of a reference to a string. `Bar.name` is an immutable reference to a string, but your only passing a copy of that reference to `Foo.change`, that copy is mutable by default.
Oct 09 2013