Forum: Ruby Range#size

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Meinrad R. (Guest)
on 2006-04-13 17:22
(Received via mailing list)
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
James G. (Guest)
on 2006-04-13 17:28
(Received via mailing list)
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:in `size'
         from (irb):4
         from :0

James Edward G. II
Jeremy T. (Guest)
on 2006-04-13 17:37
(Received via mailing list)
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...
unknown (Guest)
on 2006-04-13 17:43
(Received via mailing list)
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
Jon B. (Guest)
on 2006-04-13 19:14
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?
unknown (Guest)
on 2006-04-13 19:31
(Received via mailing list)
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
Meinrad R. (Guest)
on 2006-04-13 19:59
(Received via mailing list)
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
Florian GroÃ? (Guest)
on 2006-04-14 22:03
(Received via mailing list)
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. :)
This topic is locked and can not be replied to.