String index produces unanticipated result

I have the following string I am pulling from a file (asterisks used to
show boundaries of line, and are not actually there:

  • 9 3 3 0 0*

I want to test to see if a “9” is in the first five columns of the line.
Typically it is in column five, but not necessarily.

I tried the “puts line.strip[0]” command, which returns “57”. Huh?
Where did “57” come from?? Same thing happens with strip!.

Why isn’t this simply removing the leading white space and returning
“9”?? I don’t understand how to accomplish my task now.

I tried the online irb, and it gave me “9”, like I’d have expected.

On 2013-Apr-17, at 16:24 , Thomas L. wrote:

Why isn’t this simply removing the leading white space and returning
“9”?? I don’t understand how to accomplish my task now.

I tried the online irb, and it gave me “9”, like I’d have expected.

Your local ruby is probably <1.9 and String#[] returns the integer value
of the referenced character.

irb1.8.7> 57.chr
#1.8.7 => “9”

The online version is probably >=1.9 and String#[] returns a
one-character string.

irb2.0.0> " 9 3 3 0 0".strip[0]
#2.0.0 => “9”

-Rob

Thanks. I am running Ruby 1.8.7. That would explain why online irb gave
me what I expected.

What I used that worked was line[0…4].strip[0…0]. Makes me cringe,
but it does work.

Thanks for your explanation!

On 04/18/2013 08:24 AM, Thomas L. wrote:

Why isn’t this simply removing the leading white space and returning
“9”?? I don’t understand how to accomplish my task now.

I tried the online irb, and it gave me “9”, like I’d have expected.

The 57 you are getting is the ordinal of the string “9”;

irb(main):001:0> “9”.ord
=> 57

In Ruby 1.8 I believe an index into a string gave you this value, rather
than the character at that index. In Ruby 1.9 it was changed to give you
what you are expecting here;

irb(main):002:0> “9”[0]
=> “9”

Something like this would probably work for you in both flavours of
Ruby;

irb(main):003:0> foo.split[0,5].include? “9”
=> true

Split the string, take a slice of the first five values (columns), and
check for membership.

Sam

On Apr 18, 2013, at 7:15 AM, Robert K. [email protected]
wrote:

Why then don’t you do something like this:

irb(main):005:0> s=" 9 3 3 0 0"
=> " 9 3 3 0 0"
irb(main):006:0> s.scan(/\d+/).map(&:to_i)[0, 5].include? 9
=> true

For 1.8

irb(main):007:0> s.scan(/\d+/).map {|m| m.to_i}[0, 5].include? 9
=> true

Ruby 1.8.7 supports &:block syntax, apparently back ported from 1.9:

irb(main):001:0> RUBY_VERSION
=> “1.8.7”
irb(main):002:0> [ 1, 2, 3 ].map(&:to_s)
=> [“1”, “2”, “3”]

On Wed, Apr 17, 2013 at 10:41 PM, Thomas L.
[email protected]wrote:

Thanks. I am running Ruby 1.8.7. That would explain why online irb gave
me what I expected.

What I used that worked was line[0…4].strip[0…0]. Makes me cringe,
but it does work.

Why then don’t you do something like this:

irb(main):005:0> s=" 9 3 3 0 0"
=> " 9 3 3 0 0"
irb(main):006:0> s.scan(/\d+/).map(&:to_i)[0, 5].include? 9
=> true

For 1.8

irb(main):007:0> s.scan(/\d+/).map {|m| m.to_i}[0, 5].include? 9
=> true

Or, with a regex

irb(main):009:0> /\A\s*(?:\d+\s+){0,4}9\D/ =~ s
=> 0

Kind regards

robert