Ruby's not keyword is not not but ! (not)

Rich Steinmetz
Rich Steinmetz
Ruby's not keyword is not not but ! (not)

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... 🎡🎢

# ~/code/ruby/rubys_not_is_not_not_but_!_(not)_spec.rb

require './rubys_not_is_not_not_but_!_(not)'

RSpec.describe 'Ruby\'s not keyword' do
  let(:banger) { Banger.new }
  let(:naysayer) { Naysayer.new }

  context 'when ! is overriden' do
    it 'returns whatever value is returned by !' do
      expect(!banger).to eq :bang
      expect((not banger)).to eq :bang
    end

    it 'also returns the overriding\'s return value when called on the instance' do
      expect(banger.!).to eq :bang
    end
  end

  context 'when not is overriden' do
    it 'returns the overriding\'s return value when called on the instance' do
      expect(naysayer.not).to eq :nay
    end

    context 'but when used in the classical way before the message' do
      it 'evaluates a truthy value to false (as it always does)' do
        expect((not naysayer)).to eq false
      end
    end
  end
end
Live test-driven, read tests first

Which gives us this result:

And of course you are curious how it's implemented:

# ~/code/ruby/rubys_not_is_not_not_but_!_(not).rb

class Banger
  def !
    :bang
  end
end

class Naysayer
  def not
    :nay
  end
end
Check this masterful code on GitHub if you don't believe

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).



Join the conversation.

Great! Check your inbox and click the link
Great! Next, complete checkout for full access to Rich Stone Input Output
Welcome back! You've successfully signed in
You've successfully subscribed to Rich Stone Input Output
Success! Your account is fully activated, you now have access to all content
Success! Your billing info has been updated
Your billing was not updated