Question: I was writing a code and had an error as `Prototype after '%' for main::compareHashes`. I don't know what is a prototype, and I'm still confused after viewing numerous documents online. Can someone please explain?

Answer: 
Looking at [your previous question](https://stackoverflow.com/questions/46781792/how-to-use-reference-of-hashes-in-perl), your prototype is this:

```
sub compareHashes(%$hash1, %$hash2) { ... }

```

As a prototype, this is nonsense. Perhaps you should read [the documentation on prototypes](https://perldoc.perl.org/perlsub.html#Prototypes).

Prototypes in Perl are completely unlike prototypes in pretty any other language. Which is why expert Perl programmers do not recommend their use (outside of a tiny number of use cases where they are essential). Recent versions of Perl have added a new feature called [function signatures](https://perldoc.perl.org/perlsub.html#Signatures) which are far more like what most people expect prototypes to be - but they are currently marked as an experimental feature so not many people use them.

But let's look at your prototype and see what's wrong with it.

```
sub compareHashes(%$hash1, %$hash2) { ... }

```

Firstly, it contains what look like variable names. And Perl prototypes don't contain variable names. They are just a string of symbols describing the types of the arguments you are going to pass to the subroutine.

But the parser isn't complaining about the variable names. It doesn't get to the first variable name. It finds a problem before that. It doesn't like the `%$`. And that's because `%$` makes no sense as a prototype.

`%$` means "this subroutine takes two arguments - a hash followed by a scalar. But we (should!) know that it makes no sense to pass a scalar to a subroutine **after** a hash. That's because hash assignments are greedy and will eat up all of the remaining arguments in `@_` - leaving nothing to go into the scalar.

You are saying that you will call the subroutine like this:

```
some_sub(%hash, $scalar);

```

And within the subroutine, you'll do this:

```
my (%hash, $scalar) = @_;

```

And that just won't work. That's what the error is telling you. That your prototype is nonsense.

Don't use prototypes. Prototypes don't work the way you think they do. They are an advanced Perl feature and should only be used in specific circumstances.

**Update:** I've just noticed this in your question:

> 
> I don't know what is a prototype
> 
> 
> 

The prototype is the bit in parentheses between the subroutine name and the subroutine block. In your subroutine definition:

```
sub compareHashes(%$hash1, %$hash2) { ... }

```

The prototype is `(%$hash1, %$hash2)`. I know why people use them - they look a lot like how subroutines work in other languages, but in Perl, they are usually far more trouble than they are worth. It's best to just drop them and just define the subroutine without a prototype:

```
sub compareHashes { ... }

```
You have something like

```
sub compareHashes(%$) { ... }

```

`(%$)` is the prototype. [Prototypes](http://perldoc.perl.org/perlsub.html#Prototypes) affects how the call to the sub is parsed.

---

As for your the error you received, [perldiag](http://perldoc.perl.org/perldiag.html) provides the following explanation:

> 
> A character follows % or @ in a prototype. This is useless, since % and @ gobble the rest of the subroutine arguments.
> 
> 
> 

Whatever prototype you used makes no sense, and this is Perl's way of telling you that. You need to fix or remove `compareHashes`'s prototype.