Reputation: 135
Is there any way to push elements onto the end of a range without converting it into an array then back to a range?
r = 1..10
=> 1..10
r << 11
NoMethodError: undefined method `<<' for 1..10:Range
r.push 11
NoMethodError: undefined method `push' for 1..10:Range
Upvotes: 3
Views: 193
Reputation: 10856
You cannot extend a range by pushing the next elements to it. You can however extend the Range class to support for modifying ranges in any way you need.
class Range
def end_at(x)
Range.new(self.begin, x)
end
def start_at(x)
Range.new(x, self.end)
end
end
# Initial Range
range = 1..10
# New end
p range.end_at(100)
# => 1..100
# New start
p range.start_at(5)
# => 1..5
Upvotes: 0
Reputation: 16241
A range is simply an interval. A start and an end. You don't just push values on the end of a Range. You either convert the Range to an array
items = range.to_a
items << 11
Or you create a new range..
Range.new(range.begin, 11)
EDIT: The reason we use #begin on the range and not #first is because first
and last
build a new array from the Range, we don't want that.. we just want the begin
or end
values instead.
Upvotes: 5
Reputation: 35298
You can't. A Range is not an Array, or a Set, or a collection at all really. It's just a representation of an upper and lower bound. You can iterate one because it's possible to step between the upper and lower bounds. You can also turn one into an Array (using Range#to_a
), which just iterates and collects the values into an Array.
If you want to expand or shrink the Range, create a new Range based on its #begin
and #end
.
new_range = Range(old_range.begin, old_range.end + 1)
Upvotes: 3