The title is confusing enough, so I don't want to bore you you with words today, let's better listen to some deep-sounding Rspec code... 🎵🎶
Which gives us this result:
And of course you are curious how it's implemented:
The Moral
As you can read from the docs, Ruby's ! can be overriden so that it will even return the overriding's value when used in front of a message (like ! message(), but the not keyword overridings only have effect on the instance's return value (e.g. instance.not()).
So the moral of the story is that not uses ! somehow under the hood because when ! is overriden it has also an effect on not.
This being said, they still are not aliases since they differ a tad in functionality (namely, in precedence).