Range#member? Oddity

  • Thread starter James Edward Gray II
  • Start date
J

James Edward Gray II

I'm not understanding what I am seeing here. Can anyone please
explain why the last line of this session gives *false* as an answer?
range = ("1".."10") => "1".."10"
range.to_a => ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
range.member?("1") => true
range.member?("2")
=> false

James Edward Gray II
 
D

Daniel Berger

James said:
I'm not understanding what I am seeing here. Can anyone please explain
why the last line of this session gives *false* as an answer?
range = ("1".."10") => "1".."10"
range.to_a => ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
range.member?("1") => true
range.member?("2")
=> false

James Edward Gray II

I cannot duplicate this with 1.8.2 or 1.8.4.

- Dan
 
J

James Edward Gray II

James said:
I'm not understanding what I am seeing here. Can anyone please
explain why the last line of this session gives *false* as an answer?
range = ("1".."10") => "1".."10"
range.to_a
=> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
range.member?("1") => true
range.member?("2")
=> false
James Edward Gray II

I cannot duplicate this with 1.8.2 or 1.8.4.

Odd. I'm using 1.8.4:

$ ruby -v
ruby 1.8.4 (2005-12-24) [powerpc-darwin8.3.0]

James Edward Gray II
 
J

Justin Collins

It happens in 1.8.2 for me. It shows "1" and "10" as being in the range,
but nothing else.

[justinc@justinc-dsktp ~]$ ruby -v
ruby 1.8.2 (2004-12-25) [i586-linux-gnu]
[justinc@justinc-dsktp ~]$ irb
irb(main):001:0> range = ("1".."10")
=> "1".."10"
irb(main):002:0> range.to_a
=> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
irb(main):003:0> range.member?("1")
=> true
irb(main):004:0> range.member?("2")
=> false
irb(main):005:0> range.member?("10")
=> true
irb(main):006:0>


Note that range _isn't_ getting converted into an array.

-Justin

Daniel said:
James said:
I'm not understanding what I am seeing here. Can anyone please
explain why the last line of this session gives *false* as an answer?
range = ("1".."10") => "1".."10"
range.to_a
=> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
range.member?("1") => true
range.member?("2")
=> false

James Edward Gray II

I cannot duplicate this with 1.8.2 or 1.8.4.

- Dan
 
D

Daniel Harple

Daniel said:
I cannot duplicate this with 1.8.2 or 1.8.4.

- Dan

I'm getting this too. 1 and 10 both return true, everything else
returns false.

$ ruby -v
ruby 1.8.4 (2005-12-24) [powerpc-darwin8.3.0]
 
J

J. Ryan Sobol

James said:
I'm not understanding what I am seeing here. Can anyone please
explain why the last line of this session gives *false* as an answer?
range = ("1".."10") => "1".."10"
range.to_a
=> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
range.member?("1") => true
range.member?("2")
=> false
James Edward Gray II

I cannot duplicate this with 1.8.2 or 1.8.4.

I can.

$ ruby -v
ruby 1.8.4 (2005-12-24) [powerpc-darwin8.3.0]

~ ryan ~
 
T

tokmak tokmak

it gets odder:

irb(main):001:0> range =3D ("1".."10")
=3D> "1".."10"
irb(main):002:0> range.to_a
=3D> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
irb(main):003:0> range.member?("1")
=3D> true
irb(main):004:0> range.member?("2")
=3D> false
irb(main):005:0> range.member?("4")
=3D> false
irb(main):006:0> range.member?("9")
=3D> false
irb(main):007:0> range.member?("10")
=3D> true
irb(main):008:0> range.include?("2")
=3D> false
irb(main):009:0> range.include?("1")
=3D> true
irb(main):010:0> range =3D=3D=3D "1"
=3D> true
irb(main):011:0> range =3D=3D=3D "2"
=3D> false
irb(main):012:0> RUBY_VERSION
=3D> "1.8.2"


2006/1/13 said:
I'm not understanding what I am seeing here. Can anyone please
explain why the last line of this session gives *false* as an answer?
range =3D ("1".."10") =3D> "1".."10"
range.to_a =3D> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
range.member?("1") =3D> true
range.member?("2")
=3D> false

James Edward Gray II
 
D

Daniel Berger

James said:
James said:
I'm not understanding what I am seeing here. Can anyone please
explain why the last line of this session gives *false* as an answer?
range = ("1".."10")
=> "1".."10"
range.to_a
=> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
range.member?("1")
=> true
range.member?("2")
=> false
James Edward Gray II


I cannot duplicate this with 1.8.2 or 1.8.4.


Odd. I'm using 1.8.4:

$ ruby -v
ruby 1.8.4 (2005-12-24) [powerpc-darwin8.3.0]

James Edward Gray II

Whoops, I misspoke. I was using numbers, not strings. I do, in fact, get the
same behavior in 1.8.4 (and 1.8.2).

/me guesses randomly that it has something to do with stringified numbers in
particular.

Regards,

Dan
 
D

Dan Hinz

--=-2rqOd3MBmhtoJ8Uq7rk4
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

I don't know for sure but my guess has something to do with numbers vs
characters and whether "1".."10" expands to the same thing that 1..10
does.
1..10

Huh???

-dwh-

Daniel said:
I cannot duplicate this with 1.8.2 or 1.8.4.

- Dan

I'm getting this too. 1 and 10 both return true, everything else
returns false.

$ ruby -v
ruby 1.8.4 (2005-12-24) [powerpc-darwin8.3.0]

--
I not only live each endless day in grief, but live each day
thinking about living each day in grief.
-- C.S. Lewis

Daniel W. Hinz Xerox Corp: XOG/SEBU/MCD/EIDC/ISM&D
MS: 111-03J e-mail: (e-mail address removed)
800 Phillips Road TEL: 585.422.8078
Webster, NY 14580

--=-2rqOd3MBmhtoJ8Uq7rk4--
 
M

Matthew Desmarais

James said:
I'm not understanding what I am seeing here. Can anyone please
explain why the last line of this session gives *false* as an answer?
range = ("1".."10") => "1".."10"
range.to_a => ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
range.member?("1") => true
range.member?("2")
=> false

James Edward Gray II
Hi,

There was some discussion about this in the recent past. If my memory
serves me right (certainly an infrequent happening), the issue that
you're running into is that Range#member? is implemented as:
class Range
def member?(val)
if self.exclude_end?
(self.first <= val) and (val < self.last)
else
(self.first <= val) and (val <= self.last)
end
end
end

You should find this in both 1.8.2 and 1.8.4 I think.

There's a previous thread on ruby-talk about it, here's a link to
somewhere near the conclusion of the discussion:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/167194

Matthew
 
D

David Vallner

James said:
I'm not understanding what I am seeing here. Can anyone please explai= n =20
why the last line of this session gives *false* as an answer?
range =3D ("1".."10") =3D> "1".."10"
range.to_a
=3D> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
range.member?("1") =3D> true
range.member?("2")
=3D> false

James Edward Gray II
Hi,

There was some discussion about this in the recent past. If my memory = =20
serves me right (certainly an infrequent happening), the issue that =20
you're running into is that Range#member? is implemented as:
class Range
def member?(val)
if self.exclude_end?
(self.first <=3D val) and (val < self.last)
else
(self.first <=3D val) and (val <=3D self.last)
end
end
end

You should find this in both 1.8.2 and 1.8.4 I think.

There's a previous thread on ruby-talk about it, here's a link to =20
somewhere near the conclusion of the discussion:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/167194

Matthew


This would seem to make it an oddity of String#succ, that behaving =20
automagically, not generating successors with respect to String compariso=
n.

E.g. for any Integers i, i.succ > i. For some strings, that does't hold =20
true.

Bottom line: Don't use strings when you're really using numbers. Like in =
=20
mathemathical contexts. D'oh. You could possibly hack around that in Rang=
e =20
code to provide for data types where generating successors is inconsisten=
t =20
with comparison, but I wouldn't like to see that.

David Vallner
 
J

James Edward Gray II

You could possibly hack around that in Range code to provide for
data types where generating successors is inconsistent with
comparison, but I wouldn't like to see that.

It's not too tough in this case:
=> true

James Edward Gray II
 
D

David Vallner

It's not too tough in this case:

=3D> true

James Edward Gray II


Yes, that always works, but it beats the point of having first class =20
ranges as opposed to just having a pythonesque range function in the firs=
t =20
place. I'd personally rather coerce the strings to numbers if I know they=
=20
represent such to get more type safety and possibly some execution speed =
=20
too.

David Vallner
 
D

David Vallner

No, those methods work perfectly. The behaviour of String is the problem =
=20
here.
 
J

James Edward Gray II

No, those methods work perfectly. The behaviour of String is the
problem here.

??? How exactly is it that you believe String should behave?

James Edward Gray II
 
D

David Vallner

??? How exactly is it that you believe String should behave?

James Edward Gray II


Well, to work well in Ranges, for any String s, s.succ > s must hold true=
 
J

James Edward Gray II

Well, to work well in Ranges, for any String s, s.succ > s must
hold true.

I'm pretty sure we don't want to change the meaning of String
comparisons at this point. succ() just doesn't happened to be
defined under those terms, because then it would be a lot less useful
to us. It's hard for me to see any of that as "broken".

James Edward Gray II
 
G

gwtmp01

Well, to work well in Ranges, for any String s, s.succ > s must
hold true.

How about having Range use Object#strict_succ to generate
its sequence? Define String#strict_succ as needed to guarantee
s.succ > s and then alias strict_succ to succ for other classes
(such as Fixnum) so they don't break when used in a Range.


Gary Wright
 

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

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,120
Latest member
ShelaWalli
Top