Thread overview
struct, ref in, and UFCS
Jul 01, 2014
Puming
Jul 01, 2014
Puming
Jul 01, 2014
Ali Çehreli
Jul 01, 2014
Puming
Jul 01, 2014
bearophile
Jul 01, 2014
Puming
Jul 01, 2014
Ali Çehreli
Jul 02, 2014
Puming
July 01, 2014
Hi,

I have a struct and want to extends its methods, like:

```d
struct Server
{
  string name;
  string ip;
  int port;
  string user;
}
```

extension method here:

```d
string prompt(ref in Server server)
{
   return server.user ~ "@" ~ server.ip ~ ":" ~ server.port;
}

```

and call it with UFSC:

```d
string p = server.prompt;
```

is this the correct way to use struct and UFCS? it does not seem to copy there.
July 01, 2014
On Tuesday, 1 July 2014 at 05:09:49 UTC, Puming wrote:
> Hi,
>
> I have a struct and want to extends its methods, like:
>
> ```d
> struct Server
> {
>   string name;
>   string ip;
>   int port;
>   string user;
> }
> ```
>
> extension method here:
>
> ```d
> string prompt(ref in Server server)
> {
>    return server.user ~ "@" ~ server.ip ~ ":" ~ server.port;
> }
>
> ```
should be `server.port.to!int`;
>
> and call it with UFSC:
>
> ```d
> string p = server.prompt;
> ```
>
> is this the correct way to use struct and UFCS? it does not seem to copy there.

July 01, 2014
On 06/30/2014 10:11 PM, Puming wrote:

> On Tuesday, 1 July 2014 at 05:09:49 UTC, Puming wrote:
>> Hi,
>>
>> I have a struct and want to extends its methods, like:
>>
>> ```d
>> struct Server
>> {
>>   string name;
>>   string ip;
>>   int port;
>>   string user;
>> }
>> ```
>>
>> extension method here:
>>
>> ```d
>> string prompt(ref in Server server)
>> {
>>    return server.user ~ "@" ~ server.ip ~ ":" ~ server.port;
>> }
>>
>> ```
> should be `server.port.to!int`;

I think it should actually be server.port.to!string;

>> is this the correct way to use struct and UFCS? it does not seem to
>> copy there.

I don't understand your question but I wanted to help others by making complete code from your messages:

import std.conv;

struct Server
{
    string name;
    string ip;
    int port;
    string user;
}

string prompt(ref in Server server)
{
    return server.user ~ "@" ~ server.ip ~ ":" ~ server.port.to!string;
}

void main()
{
    auto server = Server("bzzt", "192.168.0.1", 80, "nobody");
    string p = server.prompt;
}

Ali

July 01, 2014
On Tuesday, 1 July 2014 at 05:26:47 UTC, Ali Çehreli wrote:
> On 06/30/2014 10:11 PM, Puming wrote:
>
> > On Tuesday, 1 July 2014 at 05:09:49 UTC, Puming wrote:
> >> Hi,
> >>
> >> I have a struct and want to extends its methods, like:
> >>
> >> ```d
> >> struct Server
> >> {
> >>   string name;
> >>   string ip;
> >>   int port;
> >>   string user;
> >> }
> >> ```
> >>
> >> extension method here:
> >>
> >> ```d
> >> string prompt(ref in Server server)
> >> {
> >>    return server.user ~ "@" ~ server.ip ~ ":" ~ server.port;
> >> }
> >>
> >> ```
> > should be `server.port.to!int`;
>
> I think it should actually be server.port.to!string;
>
> >> is this the correct way to use struct and UFCS? it does not
> seem to
> >> copy there.
>
> I don't understand your question but I wanted to help others by making complete code from your messages:
>
> import std.conv;
>
> struct Server
> {
>     string name;
>     string ip;
>     int port;
>     string user;
> }
>
> string prompt(ref in Server server)
> {
>     return server.user ~ "@" ~ server.ip ~ ":" ~ server.port.to!string;
> }
>
> void main()
> {
>     auto server = Server("bzzt", "192.168.0.1", 80, "nobody");
>     string p = server.prompt;
> }
>
> Ali

Thanks, This code works and my question is that is this a good practice to use `ref in` with structs instead of traditional pointer syntax (which does not play well with UFCS though) ? Is there any perfomance implications with `ref in`? I tried that it does not seem to copy the parameter value, which is good for me:


```d
#!/usr/bin/rdmd

import std.stdio;

struct Server
{
	string name;
}

string prompt(ref in Server server)
{
	__server.name = "new name";
	return server.name ~ ">";
}

Server __server;

void main()
{
	__server.name = "old_name";

	writeln(__server.prompt);
}
```

which prints

```
newname>
```

meaning the `return server.name ~ ">"` code in promt is using a reference of __server instead of copying the value.
July 01, 2014
Puming:

> is this a good practice to use `ref in` with structs instead of traditional pointer syntax (which does not play well with UFCS though) ? Is there any perfomance implications with `ref in`? I tried that it does not seem to copy the parameter value,

A "ref" is equivalent to a pointer that can't be null, so performance is the same as using a pointer (so it's good for larger structs, but not good if your struct is tiny).

Bye,
bearophile
July 01, 2014
On Tuesday, 1 July 2014 at 07:53:27 UTC, bearophile wrote:
> Puming:
>
>> is this a good practice to use `ref in` with structs instead of traditional pointer syntax (which does not play well with UFCS though) ? Is there any perfomance implications with `ref in`? I tried that it does not seem to copy the parameter value,
>
> A "ref" is equivalent to a pointer that can't be null, so performance is the same as using a pointer (so it's good for larger structs, but not good if your struct is tiny).
>
> Bye,
> bearophile

Thanks for the clarification. Now I can safely assume ref is better than pointer here because it plays nicely with UFCS.
July 01, 2014
On 07/01/2014 03:21 AM, Puming wrote:

> I can safely assume ref is better than pointer here

I agree.

> because it plays nicely with UFCS.

I don't understand that part. :) The following is the same program with just two differences: prompt() takes a pointer and 'server' is a pointer.

import std.conv;

struct Server
{
    string name;
    string ip;
    int port;
    string user;
}

string prompt(Server * server)
{
    return server.user ~ "@" ~ server.ip ~ ":" ~ server.port.to!string;
}

void main()
{
    auto server = new Server("bzzt", "192.168.0.1", 80, "nobody");
    string p = server.prompt;
}

Ali

July 02, 2014
On Tuesday, 1 July 2014 at 13:53:12 UTC, Ali Çehreli wrote:
> On 07/01/2014 03:21 AM, Puming wrote:
>
> > I can safely assume ref is better than pointer here
>
> I agree.
>
> > because it plays nicely with UFCS.
>
> I don't understand that part. :) The following is the same program with just two differences: prompt() takes a pointer and 'server' is a pointer.
>
> import std.conv;
>
> struct Server
> {
>     string name;
>     string ip;
>     int port;
>     string user;
> }
>
> string prompt(Server * server)
> {
>     return server.user ~ "@" ~ server.ip ~ ":" ~ server.port.to!string;
> }
>
> void main()
> {
>     auto server = new Server("bzzt", "192.168.0.1", 80, "nobody");
>     string p = server.prompt;
> }
>
> Ali

Wow, I've tested with some other code and pointer did not work, maybe I got something else wrong. Anyway, it's nice to know pointers also works with UFCS :-)