Peter Alfvin
Peter Alfvin

Reputation: 29409

How to find the "effective" end of a Range?

The .end of a Ruby range is the number used to specify the end of the range, whether or not the range is "exclusive of" the end. I don't understand the rationale for this design decision, but never the less, I was wondering what the most idiomatic mechanism is for determining the "effective end" of the range (i.e. greatest integer n such that range.include?(n) is true. The only mechanism I know of is last(1)[0], which seems pretty klunky.

Upvotes: 4

Views: 397

Answers (1)

toro2k
toro2k

Reputation: 19228

Use the Range#max method:

r = 1...10
r.end
# => 10
r.max
# => 9

max won't work for exclusive ranges if any of the endpoints is Float (see range_max in range.c for details):

(1.0...10.0).max
# TypeError: cannot exclude non Integer end value

(1.0..10.0).max
# => 10.0

As an exception, if begin > end, no error is raised and nil is returned:

(2.0...1.0).max
# => nil


Update: max works in costant time for any inclusive range and exclusive ranges of integers, it returns the same value as end and end-1, respectively. It is also O(1) if for the range holds that begin > end, in this case nil is returned. For exlusive ranges of non integer objects (String, Date, ...) or when a block is passed, it calls Enumerable#max so it have to travel all the elements in the range!

Upvotes: 7

Related Questions