views:

557

answers:

17

Suppose I have a class like this, in pseudo-code:

public class someClass {

    public void doSomething() {
        someClass aux = new someClass();
        // here something is done to alter the internal structures of aux
        .
        .
        this = aux;
    }
}

The attribution "this = aux", would return an error since it's not something acceptable for example in Java.

My question is, does anyone know of any other language that would understand and accept such attribution?

I know that I can circumvent this in trillions of different ways, this is not what I'm asking. :)

Thanks in advance.

EDIT: I just wanna thanks everyone's answers, I'm new on StackOverflow and am just amazed. This is place is even better than freenode. :)

+18  A: 

C++ supports:

 *this = obj;

Which is essentially the same as what you said (In other languages such as Java or C#, this is a reference. In C++ it's a pointer and should be treated as such, syntactically).


Possible use-case as questioned in comments:

class Date {
   // ...
   void Subtract(const Date& d) {
      *this = *this - d;
   }
};

Date operator -(const Date& d1, const Date &d2) {
   // ... return the difference of those dates...
}
Mehrdad Afshari
That gives me a headache thinking about it.
ojblass
It's just calling an assignment operator -- just like this->operator=(obj) -- nothing headache-worthy!
Alex Martelli
Indeed it's as easy as that. It just replaces the contents of the current object by default.
Mehrdad Afshari
*this = obj leaves the value of `this` unchanged. The OP wants to change the value of `this`.
Thomas L Holaday
@Mehrdad, are there situations where it is considered useful?
Henk Holterman
@Thomas: OP's intention is ambigous (not specified). Any direct references to it?
Mehrdad Afshari
@Henk: Yes, essentially when you want to assign all the member variables of the current objects to another object's variables(which is passed as a parameter or is a return value).
Mehrdad Afshari
Thomas L Holaday
Actually, Thomas, the OP has not said he wants to change the value of "this." He has asked whether any language understands code like that, but he hasn't yet specified what the language is supposed to understand that code TO DO. Maybe it's supposed to be an idiom that means something else, such as what Mehrdad has shown.
Rob Kennedy
@Mehrdad thanks, that what I was aiming for, yes. So C++ seems to be the closest to an answer to my question.
Cameigons
+2  A: 

Do you want to alter an object's internal structure at runtime?

That's not possible in statically typed languages like Java, Visual Basic, C++ whose programm structure is determined at compile-time whereas dynamic (interpreted) languages like JavaScript or Python would accept this.

Ex: JavaScript-objects are nothing but associative arrays.

Or do you want to assign another object to this? (which is not possible because it doesn't makes sense - see other posts)

You might want to create a copy or assign method so that you can update an object (even this) with the values of another object. E.g.

void Foo() {
   MyClass aux = new MyClass(); // ...

   this.Assign(aux);
}

void Assign(MyClass other) {
    // Make settings here
}
Dario
LISP allows to redefine symbols: (define + -) ;-)
Dario
+2  A: 

Seems that you want a dynamic typed language, a la Ruby, JRuby, or Javascript, where you can modify the internals of the object at runtime.

GClaramunt
Why is that a feature exclusive to dynamic typing?
Matt Olenik
That made no sense.
Cecil Has a Name
+1  A: 

I understand Smalltalk allows you to replace all references to an object with another object (not fast!). It's probably not the best of ideas to put in a programming language.

Tom Hawtin - tackline
+5  A: 

Delphi allows this, see Why is Self assignable in Delphi?

However, it is considered (by most) a language/compiler bug.

Henk Holterman
It just changes the value of the local variable. It has no effect on the object that received the method call. I don't regard it as a bug at all. It's just something that's rather pointless to do. At best, it's worthy of a compiler warning.
Rob Kennedy
+3  A: 

it seems the become message of Smalltalk, it can be useful in some rare circumstances

true become: false

EDIT

Python and Ruby should support something similar in order to replace a overflowed fixnum in a bigint?

dfa
ruby doesn't - fixnums are both immediate values (i.e. not references) and immutable, so if you say `a = 5; b = a` there is nothing you could do to a that would change the value of b.
Martin DeMello
+2  A: 

I'm not positive what you want this = aux to do, but the equivalent syntax in Objective-C is used all the time. The traditional form for an initializer is:

- (id)init {
    if (self = [super init]) {
        [self setVar:@"blah"];
    }
    return self;
}

The self variable is just an implicit parameter to every method in Objective-C.

Chuck
+1  A: 

The question is: why would you want to do this, and what effect would you expect it to have? Specifically: would you expect all other object that hold a reference to this to now refer to a different instance?

This would be technically possible by making all pointers indirect (which they often already are to support compacting garbage collection), but it just sounds like a very bad idea that would cause lots of hard to track bugs without any legitimately useful applications.

Michael Borgwardt
+1  A: 

smalltalk supports this via the Object>>become: method

Martin DeMello
+1  A: 

I'm not 100% sure what you try to achieve with the code. I assume that you want to copy all fields. In this case any language allows that; even Java. Only most don't have a compact way to say "copy all fields from aux". So in C/C++, you can say:

*this = *aux;

(where "this" would be a structure in C). For old C compilers, you must call memcpy() manually.

In Java, you must list all fields that you want to copy:

this.field1 = aux.field1;
this.field2 = aux.field2;
... etc ...

You can use java.lang.Reflection to copy all fields automatically; Field.setAccessible(true) is your friend. Or you could use Apache Commons Beanutils, specifically these methods.

In Python, you can easily do it like so:

self.__dict__.update(aux.__dict__)

self is the name of this in Python. This code copies all fields of the object aux into self.

Aaron Digulla
"Copy all fields", yes, that's what I was trying to achieve. My question was more about which language would do it in a way that resembled my code the most. C++ seems to be the answer then.
Cameigons
+4  A: 

Objective-C supports it, although in that case the keyword is self instead of this. In Objective-C, self is passed as a hidden parameter to all class methods (as is another hidden parameter named _cmd, which is a pointer to a C string containing the name of the message being sent, but that is irrelevant for this discussion). So, a method declared like this:

@implementation MyClass
- (void) doSomething:(int)arg1 withArg2:(float)arg2
{
    ...
}
@end

Gets turned into something like this:

// actual function name will be something else, this is just an example
void MyClass_doSomething(id self, const char *_cmd, int arg1, float arg2)
{
    ...
}

self can be reassigned to, but since it's really just a local variable, assigning to it will only have effect during the function call. Supposing that doSomething:withArg2: assigned to self, and consider the following code:

MyClass *inst = [[MyClass alloc] init];
[inst doSomething:3 withArg2:4.0f];

After the call to doSomething:withArg2:, the value of inst remains unchanged. Assigning to self there only affects the local variable named self, not the actual object.

So how is this useful? Well, when an object initialization method fails for some reason, it is customary to return nil instead of the object, and to free the object to prevent memory leaks. When you have inheritance, the subclass needs to make sure the parent's init method succeeded before it can proceed. The following is a common idiom:

- (id) init
{
    if((self = [super init]))
    {
        // initialize subclass
    }

    return self;
}

If the parent class' init routine fails, it returns nil, and the local variable self is assigned nil. The extra parentheses in the if statement are to suppress a compiler warning about using = instead of == in the if statement -- we really want = here. Finally, self is returned, which will be nil if we failed, or the object if we succeeded.

Adam Rosenfield
+4  A: 

Assigning to this or self wont have any interesting effect (if allowed) in language where this or self is a reference to the current object: you will simply assign a new object to this name, but other references to this wont be affected.

So I can do this in Python:

class someClass:
    def doSomething(self):
      aux = someClass();
      # here something is done to alter the internal structures of aux
      aux.foo = True
      self = aux

But it wont have any interesting effect since self is just a local variable that points to a someClass instance, and assigning it to another instance wont be visible outside.

You basically need a language with pointers that you can dereference like in the C++ example from Mehrdad.

On the other hand, Python allows me to dynamically change the class of an instance! This can actually be used for real. Here I make a function which will change the class of it's parameter:

def change_class(x):
    class Y(x.__class__):
        def foo(self):
            print "I'm a foo method"
            # call the super class' foo method:
            super(subclass, self).foo()
    x.__class__ = Y

It works by defining a new class called Y, which is a sub class of whatever class x happens to be. The x instance is then updated to refer to Y as it's class.

This is used for plugins in Mercurial -- new repository types subclass other repository types dynamically when the extensions are loaded. See the bookmarks extension for an example: subclass creation and class assignment. The reason why the bookmarks extension does not just define a subclass of localrepository is, that bookmarks might be combined with other extensions such as the MQ extension.

Martin Geisler
+1  A: 

Lua allows you to do this, because objects are treated as tables of values and function pointers, but I would never do this in practice - ruins far too much.

tomjen
+1  A: 
  1. If an object of type someClass is created on the stack, then its this pointer will point into the stack.
  2. If another object of type someClass is created on the heap, then its this pointer will point into the heap.
  3. When the object in (1) goes out of scope, its destructor will run. If the this pointer has been changed from pointing to stack to pointing to heap, I conjecture that there shall be undefined behavior.

I think this reasoning holds for any language which allows for automatic objects.

Thomas L Holaday
+2  A: 

this is sort of possible in the constructors of many languages, but not in other methods. For example, in python, this can be used to implement the singleton pattern.

class someClass:
    def __new__(cls):
        if hasattr(cls, "instance"):
            return cls.instance
        else
            return super(cls).__new__(cls)
    def __init__(self):
        if not hasattr(self.__class__, "instance"):
            # initialize the singleton
            self.__class__.instance = self
        else: 
            pass

Note however, the self = aux pattern is not present. In every case that self would appear, it is an argument to a method, which wouldn't have any affect, as others mention. To get the value substituting behavior, you must return a new instance from the special methods that have anything to do with that sort of thing.

TokenMacGuy
+1  A: 

It can be done with value types in C#, where it means 'write the contents of that into this:

struct Matrix2x2
{
    public float M11, M12;
    public float M21, M22;
    void Invert()
    {
     float recipDet = 1 / (M11 * M22 - M12 * M21);
     Matrix2x2 mat = new Matrix2x2()
     {
      M11 = this.M22 * recipDet,
      M12 = -this.M12 * recipDet,
      M21 = -this.M21 * recipDet,
      M22 = this.M11 * recipDet
     };
     this = mat; // Tada!
    }
}

I think csc translates into field-wise copy instructions. Edit: I checked the generated MSIL/CIL code, and it emits the stobj instruction which copies a value type into an adress, with this being ldarg.0.

Cecil Has a Name
+1  A: 

In Perl, this is as simple as reassigning the blessed object and re-blessing it with the package name of the subsumed object. If the new package is a subtype of the original, then you get basically what you want. Of course, nothing stops you from completely whacking the package name into outer space. Perl can be kinda rude that way.

james woodyatt