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
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
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).
Comments or questions? Just tweet it out to me!
Tweet
Want to get new chunks in your inbox? Hit the evanescent Subscribe button somewhere here 👇👉
Top comments (0)