Range#size


#1

dear list,

does anyone object to adding the method :size to class Range?

class Range
def size
max-min+1
end
end

i think it’s useful. maybe others too. i’d like to see it added to the
core.
here is the test for Range#size in case it’s really added.

def test_range_size
assert_equal 1, (1…1).size
assert_equal 2, (1…2).size
assert_equal 3, (1…3).size
assert_equal 0, (1…1).size
assert_equal 1, (1…2).size
end

what do you think?
– henon


#2

On Apr 13, 2006, at 8:20 AM, Meinrad R. wrote:

dear list,

does anyone object to adding the method :size to class Range?

class Range
def size
max-min+1
end
end

The problem with it is that it adds method dependancies to Range:

class Range
def size; max - min + 1 end
end
=> nil

(“AA”…“BB”).size
NoMethodError: undefined method -' for "BB":String from (irb):2:insize’
from (irb):4
from :0

James Edward G. II


#3

On 13-Apr-06, at 9:20 AM, Meinrad R. wrote:

does anyone object to adding the method :size to class Range?

Forgive me for being blunt, but Ranges don’t have a fixed size, so
how could you possibly measure it accurately? Force class
implementers to implement not only a #succ method for their objects,
but also a #range_size method which would give a formula for
calculating the size? I mean seriously…


#4

On Thu, 13 Apr 2006, Meinrad R. wrote:

i think it’s useful. maybe others too. i’d like to see it added to the core.
what do you think?
– henon

this has been discussed before. the main issue is that ranges are not
sequences, but merely endpoints.

consider:

(0.0 … 1.0).size #=> Infinite, but how to
compute?

(0.0 … 1).size #=> ?

(Rational(5,6) … Rational(5,7)).size #=> ?

infinity = Float::MAX/Float::EPSILON
(42.0 … infinity).size #=> Infinite too

a = Gem::Version.new ‘0.1.0’
b = Gem::Version.new ‘0.42.0’
(a … b ).size #=> potentially Infinite

(42 … -1).size #=> this is a valid range

if ranges are required to be continuous and bounded they become less
useful.

i think last time someone suggested an entirely new class…

regards.

-a


#5

Jeremy T. wrote:

On 13-Apr-06, at 9:20 AM, Meinrad R. wrote:

does anyone object to adding the method :size to class Range?

Forgive me for being blunt, but Ranges don’t have a fixed size, so
how could you possibly measure it accurately? Force class
implementers to implement not only a #succ method for their objects,
but also a #range_size method which would give a formula for
calculating the size? I mean seriously…

You know, it’s not as though all range operations work with all range
types anyway:

$ irb --simple-prompt

(1.0…2.0).each {|x| p x }
TypeError: can’t iterate from Float
from (irb):1:in `each’
from (irb):1

So, what would be wrong with allowing size for object that implement the

  • operation and giving an error for those that don’t?

#6

On 4/13/06, Meinrad R. removed_email_address@domain.invalid wrote:

dear list,

does anyone object to adding the method :size to class Range?

class Range
def size
max-min+1
end
end

a range like “a”…“z” would crash with #size !!
sorry for the noise. was a bad idea of mine.
please, just ignore it.

– henon


#7

Meinrad R. wrote:

class Range
def size
max-min+1
end
end

i think it’s useful. maybe others too. i’d like to see it added to the core.
here is the test for Range#size in case it’s really added.

Use .to_a.size instead. :slight_smile:


#8

On Fri, 14 Apr 2006, Jon B. wrote:

  • operation and giving an error for those that don’t?
    nothing. but try to write it. it’s harder than you might think.

you need to define as something like this:

class Range
def size
begin
first.distance last
rescue NoMethodError
begin
last.distance first
rescue NoMethodError
raise NoMethodError, “size”
end
end
end
end

class Fixnum
def distance other
(other - self).abs
end
end

class Float
def distance other
Float::MAX/Float::MIN # Infinity
end
end

in otherwords the endpoints must to the range size checking - otherwise
the
Range class would need to know about every class and how to calculate
sizes
for all M x N combinations.

if the endpoints calculate it we can easily do

(0 … 1).size

or

(0.0 … 1.0).size

but what about

(0 … 1.0).size

??

how does Range now which endpoint to use as ‘other’? if we use 1.0 it
works.
if we use 0 it does not.

it’s easy enough to fix this for only Fixnum and Float using a smart
coerce -
but then we have to deal with Rational, Bignum, Complex, String, etc.
and we
haven’t even hit user defined types.

i’m not saying there isn’t an elegant solution. but the problem becomes
evident imediately when one trys to solve the problem generically.

regards.

-a