Donkey Agony <root@[127.0.0.1]> wrote:
> Looking at Steve Litt's Basic Ruby Tutorial at ...
>
>  <http://www.troubleshooters.com/codecorn/ruby/basictutorial.htm>
>
> says he's found no easy way to replace the *first* occurrance of a
> regex match in a string with it's uppercase equivalent.  I got
> intrigued and decided to see if I (rank noob) might take a stab at it.
>
> Here's what I came up with, using Steve's framework as a base:
>
>  #!/usr/bin/env ruby
>
>  string1 = "I will drill for a well in walla walla washington."
>  string2 = string1.dup
>
>  def methodA(s)  # this works, but requires 2 lines
>    regex = /w.ll/
>    s.sub(regex, regex.match(s)[0].upcase)
>  end

It's especially silly as it matches the RX *twice* against the string.

>  def methodB(s)  # this doesn't work, "will" stays lowercase
>    s.sub(/w.ll/, '\0'.upcase)
>  end

Of course, you just upcase the string '\0'.  Your call is equivalent to

s.sub(/w.ll/, '\0')

>  puts "Original: " + string1 + "\nMethod A: " \
>       + methodA(string1)
>
>  puts "\n\nOriginal: " + string2 + "\nMethod B: " \
>       + methodB(string2)
>
>
> methodA() returns:
>
>  I WILL drill for a well in walla walla washington.
>
> but "will" is still lowercase after methodB().  How might the
> one-liner in methodB() be successfully rewritten?

You want the block form of sub:

>> "I will drill for a well in walla walla washington.".sub(/w.ll/){|m| 
>> m.upcase}
=> "I WILL drill for a well in walla walla washington."

>> "I will drill for a well in walla walla washington.".sub(/w.ll/){|m| 
>> m.upcase!}
=> "I WILL drill for a well in walla walla washington."

It's the only reasonable thing to do here because you won't know the matched 
text before the RX actually matched and that is the point in time where you 
have to calculate the replacement.  The non block form calculates the 
replacement *before* the invocation - of course you can use \\0, \\1 etc, to 
access parts - but you can't modify them.

Kind regards

    robert