On Jun 11, 2005, at 8:22 PM, nobu.nokada / softhome.net wrote:

> Hi,
>
> At Sun, 12 Jun 2005 04:29:27 +0900,
> Jamis Buck wrote in [ruby-talk:145177]:
>
>>    class Substring < String
>>      def sub!(pat, r=nil, &b)
>>        super(pat, r, &b)
>>
>          m = eval("proc{$~}", b).call    # get caller's MatchData
>
>>        # --------------------
>>        p $1 # -> "ll"
>>        # --------------------
>>
>          p m[1] # -> "ll"
>
>>      end
>>    end
>>

Hmmm. Either I'm misunderstanding you, or you misunderstood me. :)  
This still doesn't allow the caller of Substring#sub! to access the  
captured subgroups via the $digit variables.

However, further hunting has uncovered (among other information)  
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/79303,  
which seems to indicate that there is no way to do this in Ruby.  
Thus, I've changed my approach. I was basically trying to discover  
whether a String has been modified and was inserting code to capture  
the self-modifying methods and set a flag. Instead, I've changed it  
to do the following:

   class Substring < String
     def initialize(str="")
       super(str)
       reset_dirty!
     end

     def dirty?
       @original_contents != self
     end

     def reset_dirty!
       @original_contents = dup
     end
   end

I don't like having to do #dup, but it's not that big of a deal  
because Ruby does copy-on-write anyway and the string's contents  
won't be copied until the string is actually modified (right?).  
Anyway, this seems to work, and still allows sub! to work right with  
captured subgroups. Calling #dirty? is more expensive than I would  
like, but it won't be called very frequently.

- Jamis