range problem

R

Rasputin

From the Pickaxe book:

class VU
include Comparable

attr :volume

def initialize(volume) # 0..9
@volume = volume
end

def inspect
'#' * @volume
end

# Support for ranges
def <=>(other)
self.volume <=> other.volume
end

def succ
raise(IndexError, "Volume too big") if @volume >= 9
VU.new(@volume.succ)
end
end

irb(main):001:0> require 'vu'
=> true
irb(main):002:0> r = VU.new(0)..VU.new(9)
=> ..#########
irb(main):003:0> r.to_a
IndexError: Volume too big
from ./vu.rb:20:in `succ'
from (irb):3:in `each'
from (irb):3:in `to_a'
from (irb):3

Shouldn't the 0 to 9 range be possible?
Apparently 0 to 8 etc. works.
The succ method should only be raising the exception when @volume is 9
but to me it looks like it's raising the error at 8.

I'm not sure if it's a bug or something I'm doing wrong.
 
D

David A. Black

Hi --

class VU
include Comparable

attr :volume

def initialize(volume) # 0..9
@volume = volume
end

def inspect
'#' * @volume
end

# Support for ranges
def <=>(other)
self.volume <=> other.volume
end

def succ
raise(IndexError, "Volume too big") if @volume >= 9

Should that be > rather than >= ?


David
 
N

nobu.nokada

Hi,

At Fri, 14 May 2004 19:48:52 +0900,
Rasputin wrote in [ruby-talk:100269]:
Shouldn't the 0 to 9 range be possible?
Apparently 0 to 8 etc. works.
The succ method should only be raising the exception when @volume is 9
but to me it looks like it's raising the error at 8.

I'm not sure if it's a bug or something I'm doing wrong.

I think it's a bug.


Index: range.c
===================================================================
RCS file: /cvs/ruby/src/ruby/range.c,v
retrieving revision 1.63
diff -u -2 -p -r1.63 range.c
--- range.c 30 Dec 2003 16:36:05 -0000 1.63
+++ range.c 14 May 2004 11:07:43 -0000
@@ -142,15 +142,4 @@ range_eq(range, obj)

static int
-r_lt(a, b)
- VALUE a, b;
-{
- VALUE r = rb_funcall(a, id_cmp, 1, b);
-
- if (NIL_P(r)) return Qfalse;
- if (rb_cmpint(r, a, b) < 0) return Qtrue;
- return Qfalse;
-}
-
-static int
r_le(a, b)
VALUE a, b;
@@ -158,7 +147,6 @@ r_le(a, b)
VALUE r = rb_funcall(a, id_cmp, 1, b);

- if (NIL_P(r)) return Qfalse;
- if (rb_cmpint(r, a, b) <= 0) return Qtrue;
- return Qfalse;
+ if (NIL_P(r)) return -1;
+ return 1 - rb_cmpint(r, a, b);
}

@@ -248,6 +236,8 @@ range_each_func(range, func, v, e, arg)
void *arg;
{
+ int c;
+
if (EXCL(range)) {
- while (r_lt(v, e)) {
+ while ((c = r_le(v, e)) > 1) {
(*func)(v, arg);
v = rb_funcall(v, id_succ, 0, 0);
@@ -255,6 +245,7 @@ range_each_func(range, func, v, e, arg)
}
else {
- while (r_le(v, e)) {
+ while ((c = r_le(v, e)) > 0) {
(*func)(v, arg);
+ if (c == 1) break;
v = rb_funcall(v, id_succ, 0, 0);
}
@@ -611,11 +602,6 @@ range_include(range, val)
beg = rb_ivar_get(range, id_beg);
end = rb_ivar_get(range, id_end);
- if (r_le(beg, val)) {
- if (EXCL(range)) {
- if (r_lt(val, end)) return Qtrue;
- }
- else {
- if (r_le(val, end)) return Qtrue;
- }
+ if (r_le(beg, val) > 0) {
+ if (r_le(val, end) > EXCL(range)) return Qtrue;
}
return Qfalse;
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top