2018-03-04 10:09:32 -05:00
|
|
|
require_relative '../spec_helper'
|
2017-05-07 08:04:49 -04:00
|
|
|
|
|
|
|
describe 'Optional variable assignments' do
|
|
|
|
describe 'using ||=' do
|
|
|
|
describe 'using a single variable' do
|
|
|
|
it 'assigns a new variable' do
|
|
|
|
a ||= 10
|
|
|
|
|
|
|
|
a.should == 10
|
|
|
|
end
|
|
|
|
|
|
|
|
it 're-assigns an existing variable set to false' do
|
|
|
|
a = false
|
|
|
|
a ||= 10
|
|
|
|
|
|
|
|
a.should == 10
|
|
|
|
end
|
|
|
|
|
|
|
|
it 're-assigns an existing variable set to nil' do
|
|
|
|
a = nil
|
|
|
|
a ||= 10
|
|
|
|
|
|
|
|
a.should == 10
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not re-assign a variable with a truthy value' do
|
|
|
|
a = 10
|
|
|
|
a ||= 20
|
|
|
|
|
|
|
|
a.should == 10
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not evaluate the right side when not needed' do
|
|
|
|
a = 10
|
|
|
|
a ||= raise('should not be executed')
|
|
|
|
a.should == 10
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not re-assign a variable with a truthy value when using an inline rescue' do
|
|
|
|
a = 10
|
|
|
|
a ||= 20 rescue 30
|
|
|
|
|
|
|
|
a.should == 10
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'using a accessor' do
|
|
|
|
before do
|
|
|
|
klass = Class.new { attr_accessor :b }
|
|
|
|
@a = klass.new
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'assigns a new variable' do
|
|
|
|
@a.b ||= 10
|
|
|
|
|
|
|
|
@a.b.should == 10
|
|
|
|
end
|
|
|
|
|
|
|
|
it 're-assigns an existing variable set to false' do
|
|
|
|
@a.b = false
|
|
|
|
@a.b ||= 10
|
|
|
|
|
|
|
|
@a.b.should == 10
|
|
|
|
end
|
|
|
|
|
|
|
|
it 're-assigns an existing variable set to nil' do
|
|
|
|
@a.b = nil
|
|
|
|
@a.b ||= 10
|
|
|
|
|
|
|
|
@a.b.should == 10
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not re-assign a variable with a truthy value' do
|
|
|
|
@a.b = 10
|
|
|
|
@a.b ||= 20
|
|
|
|
|
|
|
|
@a.b.should == 10
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not evaluate the right side when not needed' do
|
|
|
|
@a.b = 10
|
|
|
|
@a.b ||= raise('should not be executed')
|
|
|
|
@a.b.should == 10
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not re-assign a variable with a truthy value when using an inline rescue' do
|
|
|
|
@a.b = 10
|
|
|
|
@a.b ||= 20 rescue 30
|
|
|
|
|
|
|
|
@a.b.should == 10
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'using &&=' do
|
|
|
|
describe 'using a single variable' do
|
|
|
|
it 'leaves new variable unassigned' do
|
|
|
|
a &&= 10
|
|
|
|
|
|
|
|
a.should == nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'leaves false' do
|
|
|
|
a = false
|
|
|
|
a &&= 10
|
|
|
|
|
|
|
|
a.should == false
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'leaves nil' do
|
|
|
|
a = nil
|
|
|
|
a &&= 10
|
|
|
|
|
|
|
|
a.should == nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not evaluate the right side when not needed' do
|
|
|
|
a = nil
|
|
|
|
a &&= raise('should not be executed')
|
|
|
|
a.should == nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does re-assign a variable with a truthy value' do
|
|
|
|
a = 10
|
|
|
|
a &&= 20
|
|
|
|
|
|
|
|
a.should == 20
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does re-assign a variable with a truthy value when using an inline rescue' do
|
|
|
|
a = 10
|
|
|
|
a &&= 20 rescue 30
|
|
|
|
|
|
|
|
a.should == 20
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'using a single variable' do
|
|
|
|
before do
|
|
|
|
klass = Class.new { attr_accessor :b }
|
|
|
|
@a = klass.new
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'leaves new variable unassigned' do
|
|
|
|
@a.b &&= 10
|
|
|
|
|
|
|
|
@a.b.should == nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'leaves false' do
|
|
|
|
@a.b = false
|
|
|
|
@a.b &&= 10
|
|
|
|
|
|
|
|
@a.b.should == false
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'leaves nil' do
|
|
|
|
@a.b = nil
|
|
|
|
@a.b &&= 10
|
|
|
|
|
|
|
|
@a.b.should == nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not evaluate the right side when not needed' do
|
|
|
|
@a.b = nil
|
|
|
|
@a.b &&= raise('should not be executed')
|
|
|
|
@a.b.should == nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does re-assign a variable with a truthy value' do
|
|
|
|
@a.b = 10
|
|
|
|
@a.b &&= 20
|
|
|
|
|
|
|
|
@a.b.should == 20
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does re-assign a variable with a truthy value when using an inline rescue' do
|
|
|
|
@a.b = 10
|
|
|
|
@a.b &&= 20 rescue 30
|
|
|
|
|
|
|
|
@a.b.should == 20
|
|
|
|
end
|
|
|
|
end
|
2018-04-28 15:50:06 -04:00
|
|
|
|
|
|
|
describe 'using a #[]' do
|
|
|
|
before do
|
|
|
|
@a = {}
|
2018-08-03 12:19:40 -04:00
|
|
|
klass = Class.new do
|
|
|
|
def [](k)
|
|
|
|
@hash ||= {}
|
|
|
|
@hash[k]
|
|
|
|
end
|
|
|
|
|
|
|
|
def []=(k, v)
|
|
|
|
@hash ||= {}
|
|
|
|
@hash[k] = v
|
|
|
|
7
|
|
|
|
end
|
|
|
|
end
|
|
|
|
@b = klass.new
|
2018-04-28 15:50:06 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'leaves new variable unassigned' do
|
|
|
|
@a[:k] &&= 10
|
|
|
|
|
|
|
|
@a.key?(:k).should == false
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'leaves false' do
|
|
|
|
@a[:k] = false
|
|
|
|
@a[:k] &&= 10
|
|
|
|
|
|
|
|
@a[:k].should == false
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'leaves nil' do
|
|
|
|
@a[:k] = nil
|
|
|
|
@a[:k] &&= 10
|
|
|
|
|
|
|
|
@a[:k].should == nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not evaluate the right side when not needed' do
|
|
|
|
@a[:k] = nil
|
|
|
|
@a[:k] &&= raise('should not be executed')
|
|
|
|
@a[:k].should == nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does re-assign a variable with a truthy value' do
|
|
|
|
@a[:k] = 10
|
|
|
|
@a[:k] &&= 20
|
|
|
|
|
|
|
|
@a[:k].should == 20
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does re-assign a variable with a truthy value when using an inline rescue' do
|
|
|
|
@a[:k] = 10
|
|
|
|
@a[:k] &&= 20 rescue 30
|
|
|
|
|
|
|
|
@a[:k].should == 20
|
|
|
|
end
|
2018-08-03 12:19:40 -04:00
|
|
|
|
|
|
|
it 'returns the assigned value, not the result of the []= method with ||=' do
|
|
|
|
(@b[:k] ||= 12).should == 12
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns the assigned value, not the result of the []= method with +=' do
|
|
|
|
@b[:k] = 17
|
|
|
|
(@b[:k] += 12).should == 29
|
|
|
|
end
|
2018-04-28 15:50:06 -04:00
|
|
|
end
|
2017-05-07 08:04:49 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
describe 'using compunded constants' do
|
2018-08-27 10:25:00 -04:00
|
|
|
before :each do
|
|
|
|
Object.send(:remove_const, :A) if defined? Object::A
|
|
|
|
end
|
|
|
|
|
|
|
|
after :each do
|
2017-05-07 08:04:49 -04:00
|
|
|
Object.send(:remove_const, :A) if defined? Object::A
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'with ||= assignments' do
|
|
|
|
Object::A ||= 10
|
|
|
|
Object::A.should == 10
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'with ||= do not reassign' do
|
|
|
|
Object::A = 20
|
|
|
|
Object::A ||= 10
|
|
|
|
Object::A.should == 20
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'with &&= assignments' do
|
|
|
|
Object::A = 20
|
|
|
|
-> {
|
|
|
|
Object::A &&= 10
|
|
|
|
}.should complain(/already initialized constant/)
|
|
|
|
Object::A.should == 10
|
|
|
|
end
|
|
|
|
|
2017-10-28 11:15:48 -04:00
|
|
|
it 'with &&= assignments will fail with non-existent constants' do
|
2017-05-07 08:04:49 -04:00
|
|
|
lambda { Object::A &&= 10 }.should raise_error(NameError)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'with operator assignments' do
|
|
|
|
Object::A = 20
|
|
|
|
-> {
|
|
|
|
Object::A += 10
|
|
|
|
}.should complain(/already initialized constant/)
|
|
|
|
Object::A.should == 30
|
|
|
|
end
|
|
|
|
|
2017-10-28 11:15:48 -04:00
|
|
|
it 'with operator assignments will fail with non-existent constants' do
|
2017-05-07 08:04:49 -04:00
|
|
|
lambda { Object::A += 10 }.should raise_error(NameError)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|