[ruby-list:50707] [Q]last_matchをブロックに渡す方法

From: "Masa Sakano" <imagine@...>
Date: 2018-10-09 10:21:33 UTC
List: ruby-list #50707
坂野正明と申します。

Rubyのメソッドから、ブロックに $1, $2 (を含めた 
Regexp.last_match) 
を渡す方法がないものか、と質問します。

背景として、 内部で String#sub (gsub) 
を呼ぶような同名の(duck-typingの)メソッドを作っています。単純化した例を挙げます。

     class C
       # Stringのインスタンス str に対して、sub() を実行
       def self.sub(str, re, &b)
         str.sub(re, &b)
       end
     end

     /(prev)/ =~ 'previous'
     p C.sub('baa', /(b)aa/){|a| a+'_'+$1}
       # => "baa_prev"  (∵ ブロック中で ($1 == 'prev'))
       # ここで "baa_b" を得る方法があるか?

Rubyでは、一般に、$1 
は、ローカル変数として扱われると理解しています。Ruby 
のローカル変数は、それを囲むスコープの変数を引き継ぎますね。したがって、上の例では、メソッド 
C.sub に与えるブロック中にある $1 
には、そのブロックを含む文の直前の正規表現評価の結果("prev")が渡っています。

しかし、ここで行いたいことは、「クラス C 
の(クラス)メソッド C.sub 
で評価された正規表現の結果」を $1 
(など)としてブロック内で扱うことです。

現実に、String#sub 
などでは、メソッド内で正規表現評価した結果が $1 
(など)としてブロックに渡されていて、そのブロックの結果をメソッド 
sub() 側から yieldできています。それと同じことを 
Ruby言語で記述したメソッド内で実現することはできないものでしょうか?
それとも、String#sub などのように、(C言語などの)Ruby 
interpreter実装言語で直接記述するしかないのでしょうか?

この件は、Stackoverflow で質問スレッドを立てました。
<https://stackoverflow.com/questions/52359278/how-to-pass-regexp-last-match-to-a-block-in-ruby/52385870>
回答がなかったので、一応、自分自身で「不可能」と回答したんですが、ひょっとしたら方法があるかも知れないと、こちらで質問する次第です。

何かヒントでもあれば、よろしくお願いします。

坂野正明

In This Thread

Prev Next