Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

I find it deeply weird that this is possible in Ruby (I won't immediately say how):

obj = #code redacted

print obj.state # Some value.

LValue = obj

print obj.state # Different value!

Your challenge is to create code roughly of this form. Create an object and assign it to a variable. It should have some defined attribute (or deterministic, idempotent method) like state above, that changes after the object is assigned to a new identifier (LValue above), even if you still use the old identifier (obj above) to refer to it.

Edit for emphasis: state or the equivalent must be idempotent, so creating an accessor that modifies the value, or for any other reason returns different results when called several times in a row, isn't a valid solution. Or, more simply, it has to be the assignment that changes the state.

Any language with assignment is eligible, although there are probably some where there's no fully legitimate solution. I'll post my Ruby answer if nobody else gets it after a few days, and accept highest-voted answers on a rolling basis.

share|improve this question
    
Must the LValue = obj line be required for state to actually change? (I could just make a property in C# that increments every time you get it) –  Tim S. yesterday
    
Yes, that's what I intended by saying the method needed to be idempotent. I'll edit to make that clearer. –  histocrat yesterday
    
Ok, thanks. I must've glossed over that part. –  Tim S. yesterday
    
Would simply returning the refcount of the object work? –  Nick T 6 mins ago
add comment

13 Answers

C++

This is trivial using the right tools.

#include <iostream>

using namespace std;

class Obj {
public:
   int state;

   Obj& operator= (Obj& foo) {
      foo.state++;
      this->state = foo.state - 2;
      return *this;
   }
};

int main() {
   Obj a, b, c, d;
   a.state = 3;
   b.state = 4;

   cout << a.state << " " << b.state << "\n";

   c = a;
   d = b;

   cout << a.state << " " << b.state << " " << c.state << " " << d.state << "\n";

   return 0;
}

Output:

3 4
4 5 2 3
share|improve this answer
8  
The moment I saw the title, I knew someone would do operator overloading. It's the obvious way. Have an upvote. –  professorfish yesterday
add comment

PHP (debug build, >= 5.4)

We use refcount of the object in a getter. (So, by the assignment, refcount increases and value changes)

class State {
    public function __get($arg) {
        ob_start();
        debug_zval_dump($this); // e.g. "object(State)#1 (0) refcount(6)"
        return ob_get_clean()[29];
    }
}

$obj = new State;
var_dump($obj->state);
$a = $obj;
var_dump($obj->state);
share|improve this answer
add comment

C#

Two simple options:

class Obj
{
    public int state;
    public static implicit operator int(Obj o)
    {
        return o.state++;
    }
}

static int LValueI;
static Obj LValueM { set { value.state++; } }
static void Main()
{
    var obj = new Obj { state = 1 };
    LValueI = obj;
    Console.WriteLine(obj.state); //2, caused by the implicit cast.

    LValueM = obj;
    Console.WriteLine(obj.state); //3, caused by the property setter.
    Console.ReadLine();
}

Or we could simply write to the same memory:

[StructLayoutAttribute(LayoutKind.Explicit)]
class Program
{
    [FieldOffset(0)]
    int state = 1;
    [FieldOffset(1)]
    int LValue;

    void Test()
    {
        var obj = this;

        Console.WriteLine(state);  //1
        LValue = state;
        Console.WriteLine(state);  //257
        Console.ReadLine();
    }
    static void Main() { new Program().Test(); }
}
share|improve this answer
add comment

Fortran 03

This is somewhat similar to Hugo's D answer, but is a little more hidden (partly because who the #$%^ knows Object Oriented Fortran)?

module objects
   implicit none

   type ObjDef
      integer :: state
    contains
      procedure :: initObject
      procedure :: printObject
      procedure :: setNew
   end type
 contains
   subroutine initObject(this)
     class(ObjDef) :: this
     this%state = this%state + 1
   end subroutine initObject

   subroutine printObject(this)
     class(ObjDef) :: this
     print '(a,i0)',"this%state = ",this%state
   end subroutine printObject

   subroutine setNew(this,that)
     class(ObjDef) :: this,that
     that%state = this%state
   end subroutine setNew

end module objects

program objectChange
   use objects
   type(ObjDef) :: a,b

   call initObject(a)
   call printObject(a)
   call b%setNew(a)
   call printObject(a)
end program objectChange

The output is

this%state = 1
this%state = 0

If you can figure out what happened, bonus points to you! If not:

When calling the procedure setNew in the form call b%setNew(a), b is implicitly the first argument, not the second.

share|improve this answer
add comment

PowerShell

This creates an object whose state property is the names of the variables that point to the object.

$a = @{}| Add-Member -MemberType:16 -PassThru state -Value {
        (gv|?{$this -eq $_.Value}|%{$_.Name}) -join ','} 

'Before: ' + $a.state
$b = $a
'After: ' + $a.state

Output

Before: a,this
After: a,b,this

Note: This doesn't work if the assignment happens in a child scope.

'Before: ' + $a.state
&{$b = $a}
'After: ' + $a.state

Outputs

Before: a,this
After: a,this
share|improve this answer
add comment

Perl 5

Here's one way to do it in Perl:

package Magic {
    sub new { bless {state => 1} }
    use overload '""' => sub { $_[0]{state}++ };
}
use feature 'say';

my $obj = new Magic;
say $obj->{state};
substr($_, 0) = $obj;
say $obj->{state};

This outputs:

1
2

Explanation:

This is a straightforward application of overloading. Specifically, I overload the string conversion operator "", which gets called when the overloaded object is assigned to substr() (which, yes, is a legal lvalue in Perl).

There are also plenty of special variables in Perl which stringify anything assigned to them. For example, the following also works:

my $obj = new Magic;
say $obj->{state};
$0 = $obj;
say $obj->{state};

Alternative solution

Here's another way to it:

package Magic {
    use Devel::Peek 'SvREFCNT';
    sub new { bless \my $foo }
    sub state { SvREFCNT ${$_[0]} }
}
use feature 'say';

my $obj = new Magic;
say $obj->state;
my $other = $obj;
say $obj->state;

Here, state is a method (we could make it an attribute with further tie / overload shenanigans, but that would complicate things) that literally counts the number of references to the object. Thus, unlike in the first solution, you actually have to assign $obj to a normal variable that can hold an object reference to make the state change.

share|improve this answer
add comment

TeX, much shorter than other answers here

\setbox0=\hbox{Hello world!} % Put stuff in the box 0.
\message{\the\wd0}           % Print the width of the box => non-zero
\setbox2=\box0               % Put the box instead in box 2.
\message{\the\wd0}           % Now box 0 is void, hence has zero width.

As a typesetting system, TeX has a "box" type, which contains typeset material. Since the most common use case is to move this material around, split it, etc, rather than making copies of it, boxes are normally deleted when used (or rather, "box" variables are pointers and only one pointer at a time can point to an actual box in memory). No need for any magic.

share|improve this answer
add comment

D

struct Obj {
    int state;

    void opAssign (ref Obj other) {
        ++other.state;
    }
}

void main () {
    import std.stdio;

    Obj obj, lvalue;
    writeln(obj);
    lvalue = obj;
    writeln(obj);
}

Output:

Obj(0)
Obj(1)
share|improve this answer
    
Can you just... Remove those unnecessary newlines? –  TheRare 18 hours ago
    
A lot nicer to read now. –  TheRare 9 hours ago
add comment

C++

though this can be extended for other languages that supports implicit / explicit destrucors

#include <iostream>
using namespace std;

class Foo {
    int *ptr;
public:
    Foo() {
        ptr = new int(0);
    }   
    int state() {
        return *ptr;
    }
    ~Foo() {
        (*ptr)++;
    }
};
int main() {
    Foo a, b;
    cout << a.state() << " " << b.state() << "\n";
    {
        Foo c, d;
        c = a;
        d = b;
    }
   cout << a.state() << " " << b.state()  << "\n";

   return 0;
}

The default assignment operator performs a shallow copy. So the receiving object still owns the pointer and any change implicitly affects the original object;

share|improve this answer
    
Yeah, a new without a single delete in the program. Although, for this task it's good enough I think :) –  Ruslan 3 hours ago
add comment

C++ (So you guys have forgotten about unique_ptr :-) )

#include <iostream>
#include <memory>
using namespace std;
int main() {
    std::unique_ptr<int> u1(new int(0));
    std::unique_ptr<int> u2;
    std::cout<<u1.get()<<" "<<u2.get()<<" "<<std::endl;
    u2 = std::move(u1);
    std::cout<<u1.get()<<" "<<u2.get()<<" "<<std::endl;
   return 0;
}
share|improve this answer
add comment

Python 2.x

I couldn't find a proper way to do this without defining an extra class.

class State(object):
    def __init__(self):
        self.state = 0
    def __set__(self, obj, other):
        # Keep different references
        other.state += 1
        self.state += 2

class Program(object):
    obj, value = State(), State() # Create two State-objects
    def __init__(self):
        print "Before assignment:", self.obj.state, self.value.state # 0 0
        self.value = self.obj # Set value to obj (supposedly)
        print "After  assignment:", self.obj.state, self.value.state # 1 2
        self.value = self.obj
        print "2nd    assignment:", self.obj.state, self.value.state # 2 4

Program()
share|improve this answer
add comment

Python

It's cheating a little, but how about:

import gc
class A(object):
    @property
    def state(self):
        return len(gc.get_referrers(self))

a = A()
print a.state
b = {"x": a}
print a.state
a.y = a
print a.state
del a
print b["x"].state
share|improve this answer
add comment

Java

All the other solutions use their language's form of operator overloading. Java doesn't have operator overloading, so I thought I was stuck. But I came up with something.

Here's the main class:

public class Program {
    public static void main(String[] args) {
        Thing thing = new Thing(0);
        System.out.println(thing.getState());
        Thing.otherThing = thing;
        Thread.sleep(1);
        System.out.println(thing.getState());
    }
}

There are a few suspicious lines, but they wouldn't do anything if the Thing class was completely normal. It isn't:

public class Thing {
    private int state;

    public Thing(int state) {
        this.state = state;
    }

    public int getState() {
        return state;
    }

    // Please do your best to ignore the rest of this class.
    public static volatile Thing otherThing;
    static {
        Thread t = new Thread() {
            public void run() {
                Thing t = otherThing;
                while (true)
                    if (t != otherThing) {
                        t = otherThing;
                        t.state++;
                    }
            }
        };
        t.setDaemon(true);
        t.start();
    }
}

It's not guaranteed to work because of the threads, but I tested it on JDK 1.8u5, and it works there.

share|improve this answer
    
    
@KyleKanos Got rid of all unicode chars >U+00FF –  tbodt 13 mins ago
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.