String#hex confusion


(Steven Jenkins) #1

$ irb x
x(main):001:0> “This works”
=> "This works"
x(main):002:0> ‘22’
=> "22"
x(main):003:0> ‘22’.class
=> String
x(main):004:0> ‘22’.hex.to_s
=> "34"
x(main):005:0> “Why doesn’t this?”
=> "Why doesn’t this?"
x(main):006:0> ‘22’.sub(/(\d\d)/, “#{’\1’}”)
=> "22"
x(main):007:0> ‘22’.sub(/(\d\d)/, “#{’\1’.class}”)
=> "String"
x(main):008:0> ‘22’.sub(/(\d\d)/, “#{’\1’.hex.to_s}”)
=> “0”

I understand everything but the last line. What am I missing?

Steve


(Eric Sunshine) #2

You are applying ‘hex’ to the literal string “\1”. Since ‘’ is not a hex
digit, it returns 0. What you really want is:

‘22’.sub(/(\d\d)/) { “#{$1.hex.to_s}” }

– ES

···

On Sat, 21 Feb 2004 04:31:07 +0900, Steven Jenkins wrote:

x(main):008:0> ‘22’.sub(/(\d\d)/, “#{’\1’.hex.to_s}”)
=> "0"
I understand everything but the last line. What am I missing?


(Mark Hubbart) #3

try this:

irb(main):001:0> ‘22’.sub(/(\d\d)/, “#{’\1’.inspect}”)
=> “”\1""

whoa! in your example, lines 007 and 008, you are calling the #class
and #hex methods on the string literal ‘\1’, not the result of the
substitution.

Instead, you may want:

irb(main):002:0> ‘22’.sub(/(\d\d)/){$1.inspect}
=> ""22""
irb(main):003:0> ‘22’.sub(/(\d\d)/){$1.hex.to_s}
=> “34”

If you pass a block to #sub or #gsub, it passes the block and evaluates
it each time it finds a match, whereas passing a replacement string as
an argument to those methods will evaluate the string once. So any time
you want to use code in #sub or #gsub, always pass a block, or you
might get strange results.

-Mark

···

On Feb 20, 2004, at 11:31 AM, Steven Jenkins wrote:

x(main):005:0> “Why doesn’t this?”
=> "Why doesn’t this?"
x(main):006:0> ‘22’.sub(/(\d\d)/, “#{’\1’}”)
=> "22"
x(main):007:0> ‘22’.sub(/(\d\d)/, “#{’\1’.class}”)
=> "String"
x(main):008:0> ‘22’.sub(/(\d\d)/, “#{’\1’.hex.to_s}”)
=> “0”

I understand everything but the last line. What am I missing?


(Steven Jenkins) #4

Mark Hubbart wrote:

whoa! in your example, lines 007 and 008, you are calling the #class and
#hex methods on the string literal ‘\1’, not the result of the
substitution.

OK, that makes sense. ‘\1’.class == ‘22’.class. Thanks, Mark (& Eric).

Steve