Thread overview
Using "in/out/ref"
Jun 18, 2008
David Ferenczi
Jun 18, 2008
Robert Fraser
Jun 18, 2008
David Ferenczi
June 18, 2008
I would like to better understand the rationale of in/out/ref keywords, and how they should be used.

If I don't use them, the function gets a mutable copy of the variable. So the original variable won't change. At least in case of integral types. (C-like convention?) In case of objects (object references?), or pointers the function gets a mutable reference or a mutable pointer. This means that the function can change the object, which is referred by the pointer or reference. Is it right? Does this also mean that in case of objects or pointes ref is the default?

In case of object references I would always use one of the in/out/ref keywords to be explicit. (It could be also enforced by the compiler to be explicit on references.)

Please correct me, if I'm wrong.

Regards,
David




June 18, 2008
David Ferenczi wrote:
> I would like to better understand the rationale of in/out/ref keywords, and
> how they should be used.
> 
> If I don't use them, the function gets a mutable copy of the variable. So
> the original variable won't change. At least in case of integral types.
> (C-like convention?) In case of objects (object references?), or pointers
> the function gets a mutable reference or a mutable pointer. This means that
> the function can change the object, which is referred by the pointer or
> reference. Is it right? Does this also mean that in case of objects or
> pointes ref is the default?
> 
> In case of object references I would always use one of the in/out/ref
> keywords to be explicit. (It could be also enforced by the compiler to be
> explicit on references.)
> 
> Please correct me, if I'm wrong.
> 
> Regards,
> David

In the case of objects, "ref" would be "pointer to pointer". So for example:

class C {
    string s;
    this(string s) { this.s = s; }
}


void foo(C c) {
    c.s = "foo1";
    c = new C("foo2"); // Compiles, but doesn't do anything
                       // c is only changed for scope of function
}

void bar(in C c) {
    c.s = "bar1"; // Compile-time error!
    c = new C("bar2"); // Compile-time error!
}

void baz(ref C c) {
    c.s = "baz1";
    c = new C("baz2");
}

void main() {
    C c = new C("main");
    foo(c);
    writefln(c.s); // Writes "foo1"
    baz(c);
    writefln(c.s); // Writes "baz2"
}
June 18, 2008
Robert Fraser wrote:

> David Ferenczi wrote:
>> I would like to better understand the rationale of in/out/ref keywords, and how they should be used.
>> 
>> If I don't use them, the function gets a mutable copy of the variable. So the original variable won't change. At least in case of integral types. (C-like convention?) In case of objects (object references?), or pointers the function gets a mutable reference or a mutable pointer. This means that the function can change the object, which is referred by the pointer or reference. Is it right? Does this also mean that in case of objects or pointes ref is the default?
>> 
>> In case of object references I would always use one of the in/out/ref keywords to be explicit. (It could be also enforced by the compiler to be explicit on references.)
>> 
>> Please correct me, if I'm wrong.
>> 
>> Regards,
>> David
> 
> In the case of objects, "ref" would be "pointer to pointer". So for example:
> 
> class C {
>      string s;
>      this(string s) { this.s = s; }
> }
> 
> 
> void foo(C c) {
>      c.s = "foo1";
>      c = new C("foo2"); // Compiles, but doesn't do anything
>                         // c is only changed for scope of function
> }
> 
> void bar(in C c) {
>      c.s = "bar1"; // Compile-time error!
>      c = new C("bar2"); // Compile-time error!
> }
> 
> void baz(ref C c) {
>      c.s = "baz1";
>      c = new C("baz2");
> }
> 
> void main() {
>      C c = new C("main");
>      foo(c);
>      writefln(c.s); // Writes "foo1"
>      baz(c);
>      writefln(c.s); // Writes "baz2"
> }

Thank you very much! Now I understand. :-)