Range#length?

What happened to Range#length and Range#size?

I see we have Range#end, Range#last, and Range#max, but these all seem to do
the same thing. In particular, they don’t distinguish between 3…99 and
3…99.

I’m running ruby 1.7.3 (2002-10-09) [i686-linux], if that matters.

Chris

They disappeared, amidst some discussion in this group, a little while
ago. A search of the archives should help.

The reason was that a range of floats has infinite “length”
(conceptually, not literally), and a range of strings has an
expensive-to-calculate length. So the method doesn’t make sense in
general.

Gavin

···

On Wednesday, February 12, 2003, 2:44:34 AM, Chris wrote:

What happened to Range#length and Range#size?

They disappeared, amidst some discussion in this group, a little while
ago. A search of the archives should help.

···

----- Original Message -----
From: “Gavin Sinclair” gsinclair@soyabean.com.au

What happened to Range#length and Range#size?


Ahhh…

Well, it’s a shame that something wasn’t put in to refer to the last actual
element in the range. That’s actually all I want. As I said, #end, #last,
and #max all return `99’ for both 3…99 and 3…99.

Oh, well. Nothing a good ``last - (exclude_end? ? 1 : 0)‘’ can’t handle.

:slight_smile:

Chris

IMHO this makes perfect sense :

class Range
def size
case first
when String
a = i = 0
first.reverse.each_byte do |byte|
a += byte * (256 ** i) and i += 1
end
b = i = 0
last.reverse.each_byte do |byte|
b += byte * (256 ** i) and i += 1
end
return b - a + (exclude_end? ? 0 : 1)
when Float
return 1.0/0.0
end
end
end

p (‘a’ … ‘a’).size # => 1
p (‘a’ … ‘a’).size # => 0
p (‘a’ … ‘z’).size # => 26
p (‘a’ … ‘z’).size # => 25
p (‘aa’ … ‘aa’).size # => 0
p (‘aa’ … ‘ab’).size # => 2
p (‘aa’ … ‘ab’).size # => 1
p (‘aa’ … ‘zz’).size # => 6425

p (0.0 … 42.0).size # => Infinity

this length of a String Range is easily calculated by interpreting a string as
a base 256 number, eg:

‘abc’ → ‘a’[0] * (256 ** 2) + ‘b’[0] * (256 ** 1) + ‘c’[0] * (256 ** 0)

which makes it very inexpesive (and entirely accurate) to calculate especially
since the ‘normal’ String ranges are made up of quite short strings.

p (‘even this’ … ‘works quickly’).size # => 9462642498376336060692356596486

it also seems to make perfect sense for Float Ranges to have size Infinity?
this would suprise no one.

-a

···

On Wed, 12 Feb 2003, Gavin Sinclair wrote:

On Wednesday, February 12, 2003, 2:44:34 AM, Chris wrote:

What happened to Range#length and Range#size?

They disappeared, amidst some discussion in this group, a little while
ago. A search of the archives should help.

The reason was that a range of floats has infinite “length”
(conceptually, not literally), and a range of strings has an
expensive-to-calculate length. So the method doesn’t make sense in
general.

====================================

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================

Gavin Sinclair gsinclair@soyabean.com.au writes:

The reason was that a range of floats has infinite “length”
(conceptually, not literally)

Unless you think of the “length” as being “the difference between one side
and the other”. The pencil on my desk may delimit an infinite range of
positions, but the length of that range is still just shy of 4".

Or you could think of Range.length as being similar to Array.length and
being “the number of elements in the expansion of the range”.

irb(main):001:0> length = 0
=> 0
irb(main):002:0> (1.0 … 3.0).each{ length = length + 1 }
=> 1.0…3.0
irb(main):003:0> length
=> 3

···


It’s a short step from using alt.binaries.warez.protocol-droids.c3p0 to
Palpatine seeing a post along the lines of: “CA|| NE1 0N Th]5 BB0ARD T3Ll M3
H0w 2 GeT KeWL S]Th P0WeRZ!?!?!?!??!?” The rest is, well, a couple
more overly-hyped ILM graphics demos. – henke@kharendaen.krall.org in ASR

Hi,

···

In message “Re: Range#length?” on 03/02/12, “Chris Pine” nemo@hellotree.com writes:

Well, it’s a shame that something wasn’t put in to refer to the last actual
element in the range. That’s actually all I want. As I said, #end, #last,
and #max all return `99’ for both 3…99 and 3…99.

Oh, well. Nothing a good ``last - (exclude_end? ? 1 : 0)‘’ can’t handle.

Do you think of a good name for it? I’m glad to add a method if
you have a good name.

						matz.

Hi,

IMHO this makes perfect sense :

class Range
def size
case first
when String
a = i = 0
first.reverse.each_byte do |byte|
a += byte * (256 ** i) and i += 1
end
b = i = 0
last.reverse.each_byte do |byte|
b += byte * (256 ** i) and i += 1
end
return b - a + (exclude_end? ? 0 : 1)
when Float
return 1.0/0.0
end
end
end

p (‘a’ … ‘a’).size # => 1
p (‘a’ … ‘a’).size # => 0
p (‘a’ … ‘z’).size # => 26
p (‘a’ … ‘z’).size # => 25
p (‘aa’ … ‘aa’).size # => 0
p (‘aa’ … ‘ab’).size # => 2
p (‘aa’ … ‘ab’).size # => 1
p (‘aa’ … ‘zz’).size # => 6425

p (0.0 … 42.0).size # => Infinity

Interesting.

this length of a String Range is easily calculated by interpreting a string as
a base 256 number, eg:

‘abc’ → ‘a’[0] * (256 ** 2) + ‘b’[0] * (256 ** 1) + ‘c’[0] * (256 ** 0)

which makes it very inexpesive (and entirely accurate) to calculate especially
since the ‘normal’ String ranges are made up of quite short strings.

p (‘even this’ … ‘works quickly’).size # => 9462642498376336060692356596486

But ‘even this’ never reaches ‘works quickly’ under the current
String#succ behavior.

for x in ‘even this’ … ‘works quickly’

end

would be an infinite loop. Do you want to change how it works (to
something doesn’t work for multibyte characters)?

it also seems to make perfect sense for Float Ranges to have size Infinity?
this would suprise no one.

On the contrary,

for x in 0.0 … 42.0

end

stops.

						matz.
···

In message “Re: Range#length?!?!?” on 03/02/12, ahoward ahoward@fsl.noaa.gov writes:

Reposting this since it failed the spamblock - sorry, usenet people.
(Does the spam filter support whitelists, btw? I keep getting hit for
‘forged yahoo email’)

···

Martin DeMello martindemello@yahoo.com wrote:

ahoward ahoward@fsl.noaa.gov wrote:

it also seems to make perfect sense for Float Ranges to have size Infinity?
this would suprise no one.

It’d surprise the heck out of me. When I’ve used float ranges, it’s
usually been for Range#include?, and as a convenient way to carry the
two endpoints of a segment around. I’d definitely expect size to return
last-first.

What’s iffy is #each for float ranges. That one is IMO ‘surprising’ no
matter what it does.

Also, speaking of Ranges of Floats, I think the following is a bug:

zem@timbit:~$ ruby -e “(1.0…6.5).step(1.5) {|i| p i}”
1.0
2.5
4.0
5.5
zem@timbit:~$ ruby -e “(1.0…6.5).step(0.5) {|i| p i}”
-e:1:in `step’: step can’t be <= 0 (ArgumentError)
from -e:1

martin

“Chris Pine” nemo@hellotree.com wrote in message news:345501c2d1ea$798afee0$6401a8c0@MELONBALLER

Oh, well. Nothing a good ``last - (exclude_end? ? 1 : 0)‘’ can’t handle.

How about:

class Range
def count
n = 0
each { n += 1 }
n
end
end

It does return the correct answer for all ranges (if you’re patient).

No, I’m not serious!

T

it also seems to make perfect sense for Float Ranges to have size Infinity?
this would suprise no one.

It’d surprise the heck out of me. When I’ve used float ranges, it’s
usually been for Range#include?, and as a convenient way to carry the
two endpoints of a segment around. I’d definitely expect size to return
last-first.

i can see your point. however ‘last - first’ is really the distance between
the endpoints, not the range’s ‘size’. i would consider length or distance to
be better method names for ‘last - first’. looking at dictionary.com i found

size :
1.The physical dimensions, proportions, magnitude, or extent of an object


Syn: Dimension; bigness; largeness; greatness; magnitude.

and in any set theory book i’ve seen

dimension ( [0.0, 42.0) )
or
bigness ( [0.0, 42.0) )
or
magnitute ( [0.0, 42.0) )
or

would all imply infinity.

in the case of Fixnum’s the ‘size’ and ‘length’ of an interval.

from the picaxe


A Range represents an interval—a set of values with a start and an end.

Ranges can be constructed using objects of any type, as long as the objects
can be compared using their <=> operator and they support the succ method to
return the next object in sequence.

so a Range HAS a start and end, but it IS a SET. all that is required to be a
set is to implement <=> and succ, which Floats do. using your logic what
would be the size of

(0.0 … 42.0)

42.0 right

how about this then

(0.0 … 42.0)

surely it should be ‘just a little’ bigger than (0.0 … 42.0).size right?
this is why i say it makes sense to be able to access first and last but
suggest that size → Infinity is much more inline with the semantics of what a
set of floats in the real world is.

What’s iffy is #each for float ranges. That one is IMO ‘surprising’ no
matter what it does.

completely agree for the same reasons.

-a

···

On Wed, 12 Feb 2003, Martin DeMello wrote:

ahoward ahoward@fsl.noaa.gov wrote:

====================================

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================

I suggest Range#endpoint.

-rh

···

On Tuesday, February 11, 2003, at 01:12 PM, Yukihiro Matsumoto wrote:

Hi,

In message “Re: Range#length?” > on 03/02/12, “Chris Pine” nemo@hellotree.com writes:

Well, it’s a shame that something wasn’t put in to refer to the last
actual
element in the range. That’s actually all I want. As I said, #end,
#last,
and #max all return `99’ for both 3…99 and 3…99.

Oh, well. Nothing a good ``last - (exclude_end? ? 1 : 0)‘’ can’t
handle.

Do you think of a good name for it? I’m glad to add a method if
you have a good name.

  					matz.

Robert Hahn,
Senior Web Developer,
Quarry Integrated Communications

Yukihiro Matsumoto wrote:

Hi,

Well, it’s a shame that something wasn’t put in to refer to the last actual
element in the range. That’s actually all I want. As I said, #end, #last,
and #max all return `99’ for both 3…99 and 3…99.

Oh, well. Nothing a good ``last - (exclude_end? ? 1 : 0)‘’ can’t handle.

Do you think of a good name for it? I’m glad to add a method if
you have a good name.

  					matz.

How about “last_member”?

–Vraj

···

In message “Re: Range#length?” > on 03/02/12, “Chris Pine” nemo@hellotree.com writes:

It doesn’t seem to work for general ranges:

r = “a”…“z”
==>“a”…“z”
r.last - (r. exclude_end? ? 1 : 0)
NoMethodError: undefined method `-’ for “z”:String
from (irb):4

···

On 2003-02-12 03:12:19 +0900, Yukihiro Matsumoto wrote:

Do you think of a good name for it? I’m glad to add a method if
you have a good name.


The whole problem with the world is that fools and fanatics are always
so certain of themselves, but wiser people so full of doubts.
– Bertand Russell

Interesting.

is that good, or bad? :wink:

But ‘even this’ never reaches ‘works quickly’ under the current
String#succ behavior.

for x in ‘even this’ … ‘works quickly’

end

would be an infinite loop.

thechnically so is

for x in 0.0 … 42.0

end

just because one can designate the beginning and ending of range doesn’t mean
one MUST be able it iterate over it does it? (asking)

i guess the question is WHAT a Range of strings is :

  • all possible comibnations between start and end
  • a linear (succ) progression between start and end

it seems as if viewing the bytes (mulibytes) of a string as base 256 (or
sizeof multibyte) digits would allow your example to iterater properly since
semantically once you incremented

‘even this’

upto

‘w\000\000\000\000\000\000\000\000\000\000\000\000\000\000’

you could then begin incrementing only [1…-1] untill you had

‘wo\000\000\000\000\000\000\000\000\000\000\000\000\000’

you could then begin incrementing only [2…-1] untill you had

‘wor\000\000\000\000\000\000\000\000\000\000\000\000’

eg. the Range ‘foo’ … ‘bar’ represents all the words greater than or equal
to ‘foo’ but less than ‘bar’. this seems to make some sort of sense doesn’t
it?

perhaps i’m overlooking something here…

so i guess i am reccomending that succ stay the same, but that iteration of
string Ranges use my algorithim to generate all words > or == to start and <
end (iff exclusive?).

Do you want to change how it works (to something doesn’t work for
multibyte characters)?

couldn’t one simply substitute 256 → sizeof(byte) and maintain my original
algorithim?

it also seems to make perfect sense for Float Ranges to have size Infinity?
this would suprise no one.

On the contrary,

for x in 0.0 … 42.0

end

stops.

confused ??

irb(main):001:0> for x in 0.0 … 42.0; end
TypeError: cannot iterate from Float
from (irb):1:in `each’
from (irb):1

-a

···

On Wed, 12 Feb 2003, Yukihiro Matsumoto wrote:

====================================

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================

it also seems to make perfect sense for Float Ranges to have size Infinity?
this would suprise no one.

It’d surprise the heck out of me. When I’ve used float ranges, it’s
usually been for Range#include?, and as a convenient way to carry the
two endpoints of a segment around. I’d definitely expect size to return
last-first.

i can see your point. however ‘last - first’ is really the distance between
the endpoints, not the range’s ‘size’. i would consider length or distance to
be better method names for ‘last - first’. looking at dictionary.com i found
[…]
But then, for “range” itself you get results including:

  1. The maximum extent or distance limiting operation, action, or
    effectiveness, as of a projectile, aircraft, radio signal, or
    sound.
  2. The maximum distance that can be covered by a vehicle with
    a specified payload before its fuel supply is exhausted.
  3. The distance between a projectile weapon and its target.

each of which include “distance” in the definition of range.
range.distance would mean the distance of the distance? :slight_smile:

and in any set theory book i’ve seen

dimension ( [0.0, 42.0) )
or
bigness ( [0.0, 42.0) )
or
magnitute ( [0.0, 42.0) )
or

would all imply infinity.

Except that floats aren’t reals, so are not infinitely precise, so
there is a finite number between two values.

in the case of Fixnum’s the ‘size’ and ‘length’ of an interval.

from the picaxe


A Range represents an interval—a set of values with a start and an end.

Ranges can be constructed using objects of any type, as long as the objects
can be compared using their <=> operator and they support the succ method to
return the next object in sequence.

so a Range HAS a start and end, but it IS a SET. all that is required to be a
set is to implement <=> and succ, which Floats do. using your logic what

Really?

irb(main):046:0> 3.5.succ
NameError: undefined method succ' for 3.5:Float from (irb):46 irb(main):047:0> (3.5).succ NameError: undefined method succ’ for 3.5:Float
from (irb):47
irb(main):048:0>

would be the size of

(0.0 … 42.0)

42.0 right

how about this then

(0.0 … 42.0)

surely it should be ‘just a little’ bigger than (0.0 … 42.0).size right?

smaller. … excludes the end. This has always puzzled me, that
the longer gap (‘…’ vs ‘…’) is the shorter interval, but it’s way
too late to change now, and knowing what I know of Matz’s work,
there’s going to be a VERY good reason for this!

    Hugh
···

On Wed, 12 Feb 2003, ahoward wrote:

On Wed, 12 Feb 2003, Martin DeMello wrote:

ahoward ahoward@fsl.noaa.gov wrote:

Hi,

···

In message “Re: Range#length?” on 03/02/12, Martin DeMello martindemello@yahoo.com writes:

Also, speaking of Ranges of Floats, I think the following is a bug:

zem@timbit:~$ ruby -e “(1.0…6.5).step(1.5) {|i| p i}”
1.0
2.5
4.0
5.5
zem@timbit:~$ ruby -e “(1.0…6.5).step(0.5) {|i| p i}”
-e:1:in `step’: step can’t be <= 0 (ArgumentError)
from -e:1

Yes, thank you for reporting a bug.

						matz.

what would be the last_member of

(0.0 … 42.0) ??

-a

···

On Tue, 11 Feb 2003, Vraj Mohan wrote:

Yukihiro Matsumoto wrote:

Hi,

In message “Re: Range#length?” > > on 03/02/12, “Chris Pine” nemo@hellotree.com writes:

Well, it’s a shame that something wasn’t put in to refer to the last actual
element in the range. That’s actually all I want. As I said, #end, #last,
and #max all return `99’ for both 3…99 and 3…99.

Oh, well. Nothing a good ``last - (exclude_end? ? 1 : 0)‘’ can’t handle.

Do you think of a good name for it? I’m glad to add a method if
you have a good name.

  					matz.

How about “last_member”?

====================================

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================

We don’t want to confuse it with #end, #last, and #max (though I think these
are already deceptive and confusing). Suggestions:

  • Range#last_in_range
  • Range#last_inside
  • Range#last_from_each
  • Range#max_in_range
  • Range#max_inside
  • Range#biggest_in_range
    .
    .
    .

Just some thoughts. I was trying to convey that this is inside the range,
and not an endpoint outside the range. Anything else would be confusing,
I think.

Chris

I suggest Range#endpoint.

-rh

···

----- Original Message -----
From: “Robert Hahn” rhahn@tenletters.com

On Tuesday, February 11, 2003, at 01:12 PM, Yukihiro Matsumoto wrote:

Hi,

In message “Re: Range#length?” > on 03/02/12, “Chris Pine” nemo@hellotree.com writes:

Well, it’s a shame that something wasn’t put in to refer to the last
actual
element in the range. That’s actually all I want. As I said, #end,
#last,
and #max all return `99’ for both 3…99 and 3…99.

Oh, well. Nothing a good ``last - (exclude_end? ? 1 : 0)‘’ can’t
handle.

Do you think of a good name for it? I’m glad to add a method if
you have a good name.

matz.


Robert Hahn,
Senior Web Developer,
Quarry Integrated Communications

"y".succ >> "z"

But I'm darned if I can find the method with does the opposite!

Regards,

Brian.

···

On Wed, Feb 12, 2003 at 03:50:10AM +0900, Florian Frank wrote:

On 2003-02-12 03:12:19 +0900, Yukihiro Matsumoto wrote:
> Do you think of a good name for it? I'm glad to add a method if
> you have a good name.

It doesn't seem to work for general ranges:

r = "a".."z"
    ==>"a".."z"
r.last - (r. exclude_end? ? 1 : 0)
NoMethodError: undefined method `-' for "z":String
        from (irb):4

But then, for “range” itself you get results including:

  1. The maximum extent or distance limiting operation, action, or
    effectiveness, as of a projectile, aircraft, radio signal, or
    sound.
  2. The maximum distance that can be covered by a vehicle with
    a specified payload before its fuel supply is exhausted.
  3. The distance between a projectile weapon and its target.

touche! :wink:

i think it’s not quite fair though, as Range is defined as a SET of values in
the pickaxe (which, let’s face it, is essentially a language specification to
most of us).

each of which include “distance” in the definition of range.
range.distance would mean the distance of the distance? :slight_smile:

by that logic ‘distance.size’ does not make much sense either.

Except that floats aren’t reals, so are not infinitely precise, so
there is a finite number between two values.

technically, with today’s technology yes. abstractly though, they ARE reals
and nearly always have that semantic meaning. if their finiteness could be
counted on, they would be used to control for loops, but no one does that do
they?

Ranges can be constructed using objects of any type, as long as the objects
can be compared using their <=> operator and they support the succ method to
return the next object in sequence.

so a Range HAS a start and end, but it IS a SET. all that is required to be a
set is to implement <=> and succ, which Floats do. using your logic what

Really?

you are correct - but i was merely quoting the pickaxe. the point was that
their is no implication that the objects in a Range support ‘+’ or ‘-’, etc.
rather the implication is only that they are an ordered set - nothing more -
and ordered does not imply finite nor the applicability of mathmatical
operators.

would be the size of

(0.0 … 42.0)

42.0 right

how about this then

(0.0 … 42.0)

surely it should be ‘just a little’ bigger than (0.0 … 42.0).size right?

smaller. … excludes the end. This has always puzzled me, that
the longer gap (‘…’ vs ‘…’) is the shorter interval, but it’s way
too late to change now, and knowing what I know of Matz’s work,
there’s going to be a VERY good reason for this!

again, i miswrote (only ONE cup of cafe so far!) but we are on the same page
here. you didn’t address the question though - iff a range of floats is NOT
Infinity then what would the return value be for

(0.0 … 42.0).size

and

(0.0 … 42.0).size

it is impossible to define size using ‘-’ and have this make any sort of
sense since (0.0 … 42.0) > (0.0 … 42.0)!

-a

···

On Thu, 13 Feb 2003, Hugh Sasse Staff Elec Eng wrote:

====================================

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================