You have those backwards. $this is a hashref, %this is a hash. % is for hashes, @ is for arrays and $ is for scalars. A reference is always a scalar so it needs $.
You can pass a hash or a hashref into a sub, but the sub needs to be expecting one or the other. You can dereference a hashref by using %$hashref, you can make a hashref out of hash by using \%hash. So if you know what type of variable a sub is expecting, you can convert (also know as casting) one to the other.
Usually, you want to pass references around, because they don't make copies of the entire data structure. For instance, if you have a hash with 5000 items and you pass it as a hash to a sub, the sub has to make a complete copy. But if you pass it by reference, the sub just makes a copy of the reference.
There is a way to check if the value passed to a sub is a reference or not, but I'll leave that for another time.