Skip to content

Commit

Permalink
* Drop checking for nil. Allow anything to enter array.
Browse files Browse the repository at this point in the history
It's true that nil can't be meaningfully compared with numbers or strings with
<=>, but that's not the only case - comparing numbers with strings also
meaningless.
  • Loading branch information
ledestin committed Jan 31, 2014
1 parent da9d2b5 commit 822ab03
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 82 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ array.push 'b', 'a' #=> ['a', 'b']
array = SortedArrayBinary.new { |a, b| b <=> a }
array.push 'a', 'b' #=> ['b', 'a']

# Nils not allowed.
array.push nil #=> ArgumentError is raised
# Take care to only add items that can be compared with <=>.
array.push nil, 1 #=> exception is raised
```

## Performance
Expand All @@ -41,7 +41,7 @@ When #push'ing 1000 random numbers into an array:
```
sorted_array (0.0.5) 1.179088
array-sorted (1.1.2) 0.076348
sorted_array_binary (0.0.3) 0.005721
sorted_array_binary (0.0.3) 0.005244
```

## Installation
Expand Down
37 changes: 6 additions & 31 deletions lib/sorted_array_binary.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@
# array = SortedArrayBinary.new { |a, b| b <=> a }
# array.push 'a', 'b' #=> ['b', 'a']
class SortedArrayBinary < Array
def self._check_for_nil *objs #:nodoc:
raise ArgumentError, "nils aren't allowed into sorted array" \
if objs.include?(nil)
end

alias :old_insert :insert
private :old_insert
alias :old_sort! :sort!
Expand All @@ -39,7 +34,6 @@ def initialize *args, &b
if args.size == 1
# Passed initial array.
if args.first.respond_to? :each
self.class._check_for_nil *args.first
super *args
old_sort!
return
Expand All @@ -48,14 +42,9 @@ def initialize *args, &b
# Passed size and block.
if block_given?
super *args, &b
self.class._check_for_nil *self
old_sort!
return
end

# Passed size, but not obj, which means fill with nils.
raise ArgumentError, "can't fill array with nils" \
if args.first.is_a? Numeric
end

super
Expand All @@ -75,41 +64,28 @@ def _not_implemented *args #:nodoc:
alias_method m, :_not_implemented
}

# Same as Array#collect!, but:
# * Disallow nils in the resulting array.
# * The resulting array is sorted.
def collect! &b
def collect! &b #:nodoc:
replace(collect &b)
end
alias :map! :collect!

# Same as Array#concat, but:
# * Disallow nils in the passed array.
# * The resulting array is sorted.
def concat other_ary
def concat other_ary #:nodoc:
_add *other_ary
end

# Same as Array#flatten!, but:
# * Disallow nils in the resulting array.
# * The resulting array is sorted.
def flatten! *args
def flatten! *args #:nodoc:
replace(flatten *args)
end

# Add objects to array, automatically placing them according to sort order.
# Disallow nils.
# Add objects to array, automatically placing them according to sort order
# (via <=> by default).
def push *objs
_add *objs
end
alias :<< :push
alias :unshift :push

# Same as Array#replace, but:
# * Disallow nils in @other_ary.
# * The resulting array is sorted.
def replace other_ary
self.class._check_for_nil *other_ary
def replace other_ary #:nodoc:
super
old_sort! &@sort_block
self
Expand All @@ -124,7 +100,6 @@ def sort! #:nodoc:
# left public.

def _add *objs #:nodoc:
self.class._check_for_nil *objs
objs.each { |obj|
old_insert _find_insert_position(obj), obj
}
Expand Down
51 changes: 3 additions & 48 deletions spec/sorted_array_binary_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,45 +12,20 @@ def new_array_with_block
@ar = SortedArrayBinary.new
end

# {{{2 self._check_for_nil
context 'self._check_for_nil' do
it "raises exception if there's nil in passed objs" do
expect {
SortedArrayBinary._check_for_nil 'a', nil
}.to raise_error ArgumentError
end

it "doesn't raise exception if there's no nil in passed objs" do
expect {
SortedArrayBinary._check_for_nil 'a', 'b'
}.not_to raise_error
end
end

# {{{2 self.new
context 'self.new' do
it 'if passed size and obj, fills it' do
@ar = SortedArrayBinary.new 5, 'a'
@ar.should == ['a']*5
end

it 'if passed just size, raises exception' do
expect { SortedArrayBinary.new 5 }.to raise_error ArgumentError
end

it 'if passed single non-numeric argument, calls Array#new' do
expect { SortedArrayBinary.new 'a' }.to raise_error TypeError
end

context 'if passed array,' do
it 'sorts it' do
@ar = SortedArrayBinary.new ['b', 'a']
@ar.should == ['a', 'b']
end

it 'raises exception if nil found in passed array' do
expect { SortedArrayBinary.new [nil] }.to raise_error ArgumentError
end
it 'if passed array, it sorts it' do
@ar = SortedArrayBinary.new ['b', 'a']
@ar.should == ['a', 'b']
end

it 'if passed size and block, fills it and sorts it' do
Expand Down Expand Up @@ -104,12 +79,6 @@ def new_array_with_block
end
end
}

it 'raises exception if one of resulting elements is nil' do
@ar.push 'a'
expect { @ar.send(method) { nil } }.to raise_error ArgumentError
@ar.should == ['a']
end
end
}

Expand Down Expand Up @@ -143,12 +112,6 @@ def new_array_with_block
end
end
}

it 'raises exception if resulting array contains nil' do
@ar.push [nil, 1]
expect { @ar.flatten! }.to raise_error ArgumentError
@ar.should == [[nil, 1]]
end
end

# {{{2 #push
Expand Down Expand Up @@ -177,10 +140,6 @@ def new_array_with_block
@ar.push 'a', 'b'
@ar.should == ['d', 'c', 'b', 'a']
end

it 'raises exception if nil is passed' do
expect { @ar.send method, nil }.to raise_error ArgumentError
end
end
}

Expand All @@ -198,10 +157,6 @@ def new_array_with_block
end
end
}

it "doesn't allow nils" do
expect { @ar.replace [nil] }.to raise_error ArgumentError
end
end

# {{{2 #_find_insert_position
Expand Down

0 comments on commit 822ab03

Please sign in to comment.