Ranges and Enumerable problems

Okay so when I play with “!”…"~" wrong things happen.

("!"…"~").include?(“W”)
true

("!.."~").include?(" ")
false

so far so good, however.

("!"…"~").each do |c|
puts c
end

!
"

$
%
&

(
)
*
+
,

.
/
0
1
2
3
4
5
6
7
8
9
=> “!”…"~"

This is wrong!

("!"…"~").last
=> “~”

This is also right.

It looks to me like a problem with the Enumerable mixin but I guess the
question is why?


“Hey brother Christian with your high and mighty errand, Your actions
speak
so loud, I can’t hear a word you’re saying.”

-Greg Graffin (Bad Religion)

2008/7/2 Glen H. [email protected]:

(“!”…“~”).each do |c|
(
3
(“!”…“~”).last
=> “~”

This is also right.

It looks to me like a problem with the Enumerable mixin but I guess the
question is why?

Note this

irb(main):003:0> “9”.succ
=> “10”

Try this instead:

(?!..?~).each {|c| p c.chr}

irb(main):008:0> (?!..?~).include? ?
=> false

Kind regards

robert

On Wed, Jul 2, 2008 at 9:12 AM, Robert K.
[email protected]
wrote:


2

irb(main):003:0> “9”.succ
Kind regards

robert


use.inject do |as, often| as.you_can - without end

Thanks Robert,

That is interesting. I wonder why it doesn’t work as you would expect.
The
range object seems to be correct (at least through limited include?
testing)
however it returns incomplete info whenever you use an Enumerable method
or
a method that appears to use an Enumerable method.


“Hey brother Christian with your high and mighty errand, Your actions
speak
so loud, I can’t hear a word you’re saying.”

-Greg Graffin (Bad Religion)

Hi –

On Thu, 3 Jul 2008, Glen H. wrote:

false
$
/
=> “!”…"~"

=> false

Thanks Robert,

That is interesting. I wonder why it doesn’t work as you would expect. The
range object seems to be correct (at least through limited include? testing)
however it returns incomplete info whenever you use an Enumerable method or
a method that appears to use an Enumerable method.

In 1.9 you get this:

(’!’…’~’).to_a
=> ["!", “”", “#”, “$”, “%”, “&”, “’”, “(”, “)”, “*”, “+”, “,”, “-”,
“.”, “/”, “0”, “1”, “2”, “3”, “4”, “5”, “6”, “7”, “8”, “9”, “:”, “;”,
“<”, “=”, “>”, “?”, “@”, “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”, “[”, “\”, “]”, “^”, “_”, “`”, “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”, “{”, “|”, “}”, “~”]

David

Hi,

As David wrote before, have a look at the Ascii-Table.

On 02.07.2008, at 16:48, Glen H. wrote:

Okay so when I play with “!”…"~" wrong things happen.

irb(main):002:0> “!”[0]
=> 33
irb(main):003:0> “~”[0]
=> 126

("!"…"~").include?(“W”)
true

irb(main):001:0> “W”[0]
=> 87

("!.."~").include?(" ")
false

$ irb
irb(main):001:0> " "[0]
=> 32

32 is not between 33 and 126, so include?() does it right.

hth. regards, Sandor
Szücs

On Wed, Jul 2, 2008 at 10:34 AM, David A. Black [email protected]
wrote:

(“!”…“~”).each do |c|
(
3
(“!”…“~”).last
irb(main):003:0> “9”.succ

David


Rails training from David A. Black and Ruby Power and Light:
Intro to Ruby on Rails July 21-24 Edison, NJ
Advancing With Rails August 18-21 Edison, NJ
See http://www.rubypal.com for details and updates!

Thanks David,

That is good to know. Maybe I should upgrade.


“Hey brother Christian with your high and mighty errand, Your actions
speak
so loud, I can’t hear a word you’re saying.”

-Greg Graffin (Bad Religion)

On 7/2/08, Glen H. [email protected] wrote:

That is interesting. I wonder why it doesn’t work as you would expect. The
range object seems to be correct (at least through limited include? testing)
however it returns incomplete info whenever you use an Enumerable method or
a method that appears to use an Enumerable method.

It’s not Enumerable, it’s the Range class’s #each method.
In general, Ranges use the <=> operator to test against the first and
last element to determine inclusion, but they use #succ to generate
the next element for #each. Some odd behavior arises because
(s<=>s.succ) != -1 for all s.
I thought that was the whole issue, but it turns out ‘10’ <=> ‘~’ is -1.
It turns out the Range class has special code to deal with Strings -
it also checks that s.succ.length < end.length. Without that, your
example range would enumerate forever.

There has been discussion off and on about changing Range to use some
new alternate method to #succ which would guarantee ‘sane’ behavoir,
but nothing has ever come of it.

-Adam

On Wed, Jul 2, 2008 at 7:13 PM, Adam S. [email protected]
wrote:

Some odd behavior arises because
(s<=>s.succ) != -1 for all s.

Is that so???

I guess you mean there exists an s for which …

Cheers
Robert

http://ruby-smalltalk.blogspot.com/


AALST (n.) One who changes his name to be further to the front
D.Adams; The Meaning of LIFF

On 7/2/08, David A. Black [email protected] wrote:

“t”, “u”, “v”, “w”, “x”, “y”, “z”, “{”, “|”, “}”, “~”]
On 7/2/08, Adam S. [email protected] wrote:
There has been discussion off and on about changing Range to use some
new alternate method to #succ which would guarantee ‘sane’ behavoir,
but nothing has ever come of it.

Looks like I spoke too soon. Did Range#each change, or did String#succ?

On 02.07.2008 19:48, Adam S. wrote:

On 7/2/08, Robert D. [email protected] wrote:

On Wed, Jul 2, 2008 at 7:13 PM, Adam S. [email protected] wrote:

Some odd behavior arises because
(s<=>s.succ) != -1 for all s.
Is that so???

I guess you mean there exists an s for which …

I’m not sure what you mean

He meant

You said: for all s: (s<=>s.succ) != -1

He said: there exists at least one s: (s<=>s.succ) != -1

It’s probably Robert’s mathematical training which made him detect that
the two statements are not equivalent - and he is absolutely right. :slight_smile:

Kind regards

robert

On 7/2/08, Robert D. [email protected] wrote:

On Wed, Jul 2, 2008 at 7:13 PM, Adam S. [email protected] wrote:

Some odd behavior arises because
(s<=>s.succ) != -1 for all s.

Is that so???

I guess you mean there exists an s for which …

I’m not sure what you mean

irb(main):027:0> 1<=>1.succ
=> -1
irb(main):028:0> ‘a’<=>‘a’.succ
=> -1
irb(main):029:0> ‘z’<=>‘z’.succ
=> 1

On Wed, Jul 2, 2008 at 2:27 PM, Robert K.
[email protected]
wrote:

He said: there exists at least one s: (s<=>s.succ) != -1

Or another way of saying the same thing (as Robert D.):

!(for all s: (s <=>s.succ) == -1)


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On Wed, Jul 2, 2008 at 3:50 PM, Rick DeNatale [email protected]
wrote:

!(for all s: (s <=>s.succ) == -1)

Well, not really. That gives you no information as to whether such a
thing does exist. That statement would be true, but not definitive,
meaning, that it would be true if there is no s that satisfies.

I think Robert was going for “at least 1” in his statement.

But, I guess that’s just making a mountain out of a mole hill, because
I think Rick was just pointing out something, and not trying to be
being rigorously complete.

Todd

On Wed, Jul 2, 2008 at 8:27 PM, Robert K.
[email protected] wrote:

He said: there exists at least one s: (s<=>s.succ) != -1

It’s probably Robert’s mathematical training which made him detect that the
two statements are not equivalent - and he is absolutely right. :slight_smile:
You see Adam it’s not my fault I just had bad education;), sorry I
thought it was just a misstype of yours.

As there exist some s such as ( s <=> s.succ) == -1 (most of them by
the way) your statement
was wrong, I guess that you got carried away by the not, could easily
have happened to me.

! for all s: (s<=> s.succ) == -1

is true. Do we read each other now?

Cheers
Robert

2008/7/3 Todd B. [email protected]:

On Wed, Jul 2, 2008 at 5:07 PM, Todd B. [email protected] wrote:

On Wed, Jul 2, 2008 at 3:50 PM, Rick DeNatale [email protected] wrote:

!(for all s: (s <=>s.succ) == -1)

Well, not really. That gives you no information as to whether such a
thing does exist. That statement would be true, but not definitive,
meaning, that it would be true if there is no s that satisfies.

Okay, that may have been a major faux pas on my part :slight_smile:

It is. :slight_smile: not (for all e: X(e)) <=> (there is at least one e: not
X(e))

Kind regards

robert

On Wed, Jul 2, 2008 at 5:07 PM, Todd B. [email protected] wrote:

I think Rick was just pointing out something, and not trying to be
being rigorously complete.

Okay, that may have been a major faux pas on my part :slight_smile:

Todd

On Thu, Jul 3, 2008 at 5:23 AM, Robert K.
[email protected]
wrote:

Okay, that may have been a major faux pas on my part :slight_smile:

It is. :slight_smile: not (for all e: X(e)) <=> (there is at least one e: not X(e))

Yep, I remember getting A’s in my logic courses. I vaguely remembered this
as being related to De Morgan’s laws in Boolean algebra, and Wikipedia
seems
to agree
De Morgan's laws - Wikipedia


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On 7/3/08, Rick DeNatale [email protected] wrote:

On Thu, Jul 3, 2008 at 5:23 AM, Robert K. [email protected]
wrote:

2008/7/3 Todd B. [email protected]:

On Wed, Jul 2, 2008 at 5:07 PM, Todd B. [email protected] wrote:

On Wed, Jul 2, 2008 at 3:50 PM, Rick DeNatale [email protected]
wrote:

!(for all s: (s <=>s.succ) == -1)

Wow, I seem to have started quite a tangent. That’s exactly what I
was thinking, but when I translated my thoughts into pseudo-ruby, I
put the ! in the wrong place for boolean logic, which I wasn’t even
considering.

I never did get an answer to my question about v1.9 - it’s probably
time for me to install it - but until I do:
did String#succ change? Does ‘9’.succ return ‘:’ now?
Is the above statement - which was true in 1.85 - no longer true in 1.9?

-Adam

Adam my apologies, instead of logic nitpicking, which was fun of
course, I could have provided an answer to the original question too
;).
But you will not like it :frowning:

robert@roma:~ 20:27:45
437/7 > ruby1.9 -v -e ‘p “9”.succ’
ruby 1.9.0 (2007-12-25 revision 14709) [i486-linux]
“10”

Cheers
Robert


http://ruby-smalltalk.blogspot.com/


AALST (n.) One who changes his name to be further to the front
D.Adams; The Meaning of LIFF

On 7/3/08, Robert D. [email protected] wrote:

Adam my apologies, instead of logic nitpicking, which was fun of
course, I could have provided an answer to the original question too
;).
But you will not like it :frowning:

No need to apologize. Tangents can be fun.

I don’t dislike the answer - I was just curious about the change. But
now I’m wondering about David’s earlier statement that under 1.9,
(‘!’…‘~’).to_a works ‘correctly’. Does this mean that Range.each has
even more special cases for Strings? That would be unfortunate. It
seems cleaner if Range could use an alternate method (#advance ?)
which would be an alias for #succ in class Object, but would be
overridden by String and other classes where x.succ doesn’t always
compare greater than x.

-Adam