package MObjectRef;
use strict;
use vars qw($AUTOLOAD);
use overload (
  '==' => \&ref_overload_eq,
  '!=' => \&ref_overload_ne,
  'eq' => \&ref_overload_eq,
  'ne' => \&ref_overload_ne,
  '""' => \&ref_overload_stringify,
);

BEGIN {bless [], __PACKAGE__} # force refreshing of overload info if package is recompiled

use constant REF_DEBUG => 0;

use Carp;

sub new {
  my ($class, $id) = @_;
  return bless \$id, $class;
}

sub AUTOLOAD {
  my ($method) = $AUTOLOAD =~ /::([^:]+)$/;
  local $" = ', ';
  print STDOUT "[${$_[0]}]->$method(@_[1..$#_])\n" if REF_DEBUG;
  no strict 'refs';
  *{$method} = sub {
    my $self = shift;
    my $id;
    my $real = MObjectDB->get_real($id = $$self) or croak "Object #$id no longer exists";
    $real->$method(@_);
  };
  goto &$AUTOLOAD;
}

sub ref_overload_eq {
  my ($self, $other) = @_;
  
  print STDOUT "[$$self] ==\n" if REF_DEBUG;
  if (ref $other and ref $other eq ref $self) {
    return $$self == $$other;
  } else {
    return MObjectDB->get_real($$self) == $other;
  }
}

sub ref_overload_ne {
  my ($self, $other) = @_;
  
  print STDOUT "[$$self] !=\n" if REF_DEBUG;
  if (ref $other and ref $other eq ref $self) {
    return $$self != $$other;
  } else {
    return MObjectDB->get_real($$self) != $other;
  }
}

sub ref_overload_stringify {return overload::StrVal($_[0])}

sub DESTROY {}

1;
