in reply to How does my $self = (@_) actually work?

Of course it should work, because $self is a reference. Although you copied the reference from @_ to $self, you didn't copy the hash that it refers to. So when you change something via the reference, you change the original hash.

If it's just a one-level hash, you could copy it like this:

my %copy = %{ $self }; # or my $copy = { %{$self} };

If you want to copy a nested data structure, check out How do I print out or copy a recursive data structure? in the perlfaq.