On Thu, 24 Nov 2005, Warren B. wrote:
You completely lost me there. ‘01’ doesn’t go anywhere. That
string is not in the range ‘1’…‘10’, in the same way the ‘x’ is not in
the range ‘a’…‘n’.
says who? i may chose to define String#succ to do whatever i like
including the values ‘01’, ‘001’, and ‘0001’.
my point is simply that you seem to be merging the notion of ranges and
sets.
the range abstract to_a is determined by only a few things
-
the start and end points
-
the succ method of the start value and each successive succ value
remember one could do this
irb(main):003:0> class String; def succ; self == “1” ? 42 :
super; end; end
=> nil
irb(main):004:0> “1”.succ
=> 42
-
the spaceship operator for each succ value called against the
endpoint
because of this we cannot even safely call to_a on an arbitrary range.,
for instance
irb(main):002:0> (42.0 … 1.0).to_a
TypeError: can’t iterate from Float
from (irb):2:in each' from (irb):2:in
to_a’
from (irb):2
in summary a range is nothing but a set of endpoints with some
abstract/duck-type-like methods that may or may not produce a set as a
process. note that the set produced is not part of the range itself
and
can be dynamically altered or even be made to produce a different set
each
time:
harp:~ > cat a.rb
class Float
def succ
self + rand
end
end
p((4.2 … 42.0).to_a)
harp:~ > ruby a.rb
[4.2, 4.60303889967309, 5.57983848378295, 6.19446672151043,
6.92731328072508, 7.40446684874589, 7.79202463038348, 8.67552806421286,
9.42821837951244, 10.1988047216007, 11.1116769865281, 11.6169205995556,
11.9975653524073, 12.2256247650959, 12.8874200335378, 13.1557666607712,
13.6470070004444, 14.2172959192607, 15.0882979655236, 15.3487930162798,
15.9791460692026, 16.4321713791994, 17.0903318945661, 17.2967949864209,
18.2400722395741, 18.7286500286255, 19.7174743954199, 20.4528553779707,
20.953553149678, 21.0415866875269, 21.2924876748544, 22.2378099442685,
23.0076932295775, 23.0941582708386, 23.4748092012559, 23.5515124737304,
24.3463511761819, 24.6901201768951, 25.2541406207396, 26.0256212044938,
26.843159468986, 26.9579528629072, 27.01297383827, 27.7250436963749,
27.9017308958297, 28.1100643283236, 28.4480522935525, 28.6197629801695,
29.3756706791326, 29.9897540116082, 30.0057580759777, 30.7085039121469,
30.7510332074171, 30.9096299847723, 30.9314941316772, 31.3964098461468,
31.7312966347497, 32.2153802510432, 32.619498970957, 32.9731525439908,
33.3765950052407, 34.3397676884718, 35.1641816525327, 35.4891756054474,
36.2408178073905, 36.8733362068042, 37.6251560883057, 37.8047618263845,
37.8828752584342, 38.2001976403303, 38.9255502197319, 39.8027872575378,
40.0416710479264, 40.9954826039753, 41.4534375661544]
ruby 1.8.2 (2004-12-25) [i386-mswin32]
[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”, “l”, “m”, “n”,
“o”, “p”, “q”, “r”, “s”, “t”, “u”, “v”, “w”, “x”, “y”, “z”, “aa”]
Here we have a string range that has 27 “members”. Now:
not quite - we have a string range that produces 27 elements. it
does not
‘have’ or ‘contain’ them. it merely suggests this set as it’s current
thought
on what that set might be. this set definition may change - unlike the
endpoints of the range - and it is therefore not a property of the
range.
Can this really be called correct behavior of the member?() method? I
can’t see any tenable argument to say that it is.
the definition of membership may rely on endpoints only. that explains
it
perfectly.
harp:~ > irb
irb(main):001:0> ‘z’ < ‘aa’
=> false
ergo - not in the set. the confustion here is caused by exactly the
reasons
i’m explaining - String#succ has been defined not to create a
monotonically
increasing (<=>) sequence - but to produce the “next” string in an
english
sense. this is very useful for auto-generating names
irb(main):004:0> “z99”.succ
=> “aa00”
if this were a monotonically increasing set the output would be
=> “z9:”
but that sure isn’t that useful - unless you want to try to use ranges
as
sets.
the secret here is simply re-define String#succ - not Range#member. if
String#succ did a simply addition using base 255 arith you’d be set.
kind regards.
-a