Jump to page: 1 2
Thread overview
Ref and class function calls?
Apr 16, 2013
Tofu Ninja
Apr 16, 2013
John Colvin
Apr 16, 2013
John Colvin
Apr 16, 2013
Tofu Ninja
Apr 16, 2013
John Colvin
Apr 16, 2013
Regan Heath
Apr 16, 2013
Tofu Ninja
Apr 17, 2013
Regan Heath
Apr 17, 2013
Regan Heath
Apr 17, 2013
Tofu Ninja
Apr 17, 2013
Regan Heath
Apr 16, 2013
Ali Çehreli
Apr 16, 2013
Tofu Ninja
Apr 16, 2013
Ali Çehreli
Apr 17, 2013
Tofu Ninja
April 16, 2013
I could not think of what to call this because I don't know if it has a name to call it by.

Basicly what I was wondering is if their was a way in D to make a class function pass the object being called on by reference.

might be easier to show code, basically I want something like this to be possible

class A
{
     //some how signify that this function passes 'this' by reference
     public void replace()
     {
          this = new A();
     }
}

...

A a = new A();
A b = a;
b.replace();
assert(b != a);

I don't know if I am being clear or if their is something better to call this.

Thanks for the help
Tofu
April 16, 2013
On Tuesday, 16 April 2013 at 05:37:48 UTC, Tofu Ninja wrote:
> I could not think of what to call this because I don't know if it has a name to call it by.
>
> Basicly what I was wondering is if their was a way in D to make a class function pass the object being called on by reference.
>
> might be easier to show code, basically I want something like this to be possible
>
> class A
> {
>      //some how signify that this function passes 'this' by reference
>      public void replace()
>      {
>           this = new A();
>      }
> }
>
> ...
>
> A a = new A();
> A b = a;
> b.replace();
> assert(b != a);
>
> I don't know if I am being clear or if their is something better to call this.
>
> Thanks for the help
> Tofu

A member function cannot modify it's own 'this' pointer.

However, a free function can do it happily, which when combined with UFCS gives you the same syntax and behaviour:

class A {
	//......
}

void replace(ref A a)
{
	a = new A();
}

void main() {
	A a = new A();
	A b = a;
	assert(b is a);
	b.replace();
	assert(!(b is a));
}

http://dpaste.dzfl.pl/147f69e1
April 16, 2013
On Tuesday, 16 April 2013 at 14:33:21 UTC, John Colvin wrote:
> A member function cannot modify it's own 'this' pointer.
>
> However, a free function can do it happily, which when combined with UFCS gives you the same syntax and behaviour:
>
> class A {
> 	//......
> }
>
> void replace(ref A a)
> {
> 	a = new A();
> }
>
> void main() {
> 	A a = new A();
> 	A b = a;
> 	assert(b is a);
> 	b.replace();
> 	assert(!(b is a));
> }
>
> http://dpaste.dzfl.pl/147f69e1

Alternatively, if you don't actually need it to be a completely seperate new object, just re-initialised, you can just call this() inside a member function. E.g.

class A
{
     public void replace()
     {
          this();
     }
}
April 16, 2013
On Tuesday, 16 April 2013 at 14:33:21 UTC, John Colvin wrote:
> A member function cannot modify it's own 'this' pointer.
>
> However, a free function can do it happily, which when combined with UFCS gives you the same syntax and behaviour:
>
> class A {
> 	//......
> }
>
> void replace(ref A a)
> {
> 	a = new A();
> }
>
> void main() {
> 	A a = new A();
> 	A b = a;
> 	assert(b is a);
> 	b.replace();
> 	assert(!(b is a));
> }
>
> http://dpaste.dzfl.pl/147f69e1

Yes... this is what I feared. I knew I could do it like that but I was hoping a more elegant solution was available, seems like bad design to have a function that is fully intended to be a class function but not actually be able to declare it within the class block.
April 16, 2013
On Tuesday, 16 April 2013 at 14:57:11 UTC, Tofu Ninja wrote:
> On Tuesday, 16 April 2013 at 14:33:21 UTC, John Colvin wrote:
>> A member function cannot modify it's own 'this' pointer.
>>
>> However, a free function can do it happily, which when combined with UFCS gives you the same syntax and behaviour:
>>
>> class A {
>> 	//......
>> }
>>
>> void replace(ref A a)
>> {
>> 	a = new A();
>> }
>>
>> void main() {
>> 	A a = new A();
>> 	A b = a;
>> 	assert(b is a);
>> 	b.replace();
>> 	assert(!(b is a));
>> }
>>
>> http://dpaste.dzfl.pl/147f69e1
>
> Yes... this is what I feared. I knew I could do it like that but I was hoping a more elegant solution was available, seems like bad design to have a function that is fully intended to be a class function but not actually be able to declare it within the class block.

I would argue that it is better as a separate function.

Having a member function that reassigns 'this' seems a long way from least-surprise (although with UFCS the user might be none the wiser anyway).
April 16, 2013
On Tue, 16 Apr 2013 15:57:09 +0100, Tofu Ninja <emmons0@purdue.edu> wrote:

> On Tuesday, 16 April 2013 at 14:33:21 UTC, John Colvin wrote:
>> A member function cannot modify it's own 'this' pointer.
>>
>> However, a free function can do it happily, which when combined with UFCS gives you the same syntax and behaviour:
>>
>> class A {
>> 	//......
>> }
>>
>> void replace(ref A a)
>> {
>> 	a = new A();
>> }
>>
>> void main() {
>> 	A a = new A();
>> 	A b = a;
>> 	assert(b is a);
>> 	b.replace();
>> 	assert(!(b is a));
>> }
>>
>> http://dpaste.dzfl.pl/147f69e1
>
> Yes... this is what I feared. I knew I could do it like that but I was hoping a more elegant solution was available, seems like bad design to have a function that is fully intended to be a class function but not actually be able to declare it within the class block.

I would question always question "fully intended" on a case by case basis:
http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197

I agree that grouping functions together that should be used together, or on the same type of object is a good idea from an organisational point of view but that shouldn't be the only reason for making them class member functions.

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
April 16, 2013
On 04/16/2013 07:57 AM, Tofu Ninja wrote:

> seems like bad design to
> have a function that is fully intended to be a class function but not
> actually be able to declare it within the class block.

It would be bad design if a class variable decided to refer to another object without the owner of that variable knowing about it.

I think the most accurate reason why this is not possible is that the 'this' reference inside a member function is just a local class variable (or "handle"). If you could make it refer to a new object, then only that local reference would be affected and the outside variable would not know about it.

Ali

April 16, 2013
On Tuesday, 16 April 2013 at 15:27:10 UTC, Ali Çehreli wrote:
> On 04/16/2013 07:57 AM, Tofu Ninja wrote:
> It would be bad design if a class variable decided to refer to another object without the owner of that variable knowing about it.


I don't know, It seems like the caller of the function should know what he/she is calling. I don't make practice of calling a function with out knowing what it will do first, the caller should know that their is a chance the variable would be reassigned if its a 'ref this function'.

The same thing can be said about normal ref arguments. The caller knows that if they pass a variable into a function that has a ref argument, then there's a chance that the variable will be reassigned. Its the responsibility of the caller to know what they are calling and what might happen because of it.

And their are plenty of cases that a 'ref this function' is desirable. Simple example, a linked list head with a push function. It reassigns the head variable to what you are pushing and chains the rest after it. It makes logical sense to be able to do head.push(...) and it makes sense for this to be a class function.

Tofu
April 16, 2013
On Tuesday, 16 April 2013 at 15:23:56 UTC, Regan Heath wrote:
> I would question always question "fully intended" on a case by case basis:
> http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197
>
> I agree that grouping functions together that should be used together, or on the same type of object is a good idea from an organisational point of view but that shouldn't be the only reason for making them class member functions.
>
> R

I think a lot of people give too much credit to encapsulation. I mean don't get me wrong its cool and all and it has its place, but it seems like some people make it seem a lot more important than it really is. I mean having lots of encapsulation really doesn't do anything for your program, it won't run faster or do more things. If any thing, more often than not, it makes things run slower, as you can't see what's in the black box.

Thats just my opinion on the whole thing...

I am actually hesitant to post this because I don't want to start a debate over encapsulation.... I really hope i don't start a debate...
April 16, 2013
On 04/16/2013 08:44 AM, Tofu Ninja wrote:

> On Tuesday, 16 April 2013 at 15:27:10 UTC, Ali Çehreli wrote:
>> On 04/16/2013 07:57 AM, Tofu Ninja wrote:
>> It would be bad design if a class variable decided to refer to another
>> object without the owner of that variable knowing about it.
>
>
> I don't know, It seems like the caller of the function should know what
> he/she is calling. I don't make practice of calling a function with out
> knowing what it will do first, the caller should know that their is a
> chance the variable would be reassigned if its a 'ref this function'.

You are right.

I think the problem then is that 'this' is yet another handle to the object. Changing it wouldn't make any effect on the outside world:

  auto a = new Class();
  auto b = a;             // now two handles
  b.foo();  // let's assume that foo can assign to 'this'

When that happens, would you expect a and b also become handles to the new object? It could I guess, but it sounds impractical in a system language. The runtime does not maintain a record of what handles share the same object.

> The same thing can be said about normal ref arguments. The caller knows
> that if they pass a variable into a function that has a ref argument,
> then there's a chance that the variable will be reassigned. Its the
> responsibility of the caller to know what they are calling and what
> might happen because of it.

Agreed.

> And their are plenty of cases that a 'ref this function' is desirable.
> Simple example, a linked list head with a push function. It reassigns
> the head variable to what you are pushing and chains the rest after it.

What happens to other references to the old head? Do they continue pointing at the neck? Maybe that is understandable...

> It makes logical sense to be able to do head.push(...)

I can't see it that way yet.

> and it makes
> sense for this to be a class function.

And it wouldn't make sense if it were a non-member function? If so, I don't see it yet.

>
> Tofu

Ali

« First   ‹ Prev
1 2