2011-06-19 6 views
0

Rubyに内部DSLを書きます。現在、このミニ言語の基本構造は、ブロックduringを含む必要があり、必要に応じていくつかの方法が追加されています。例えば:Rubyでブロックを実行していないブロックがあるかどうかを確認します

do 
    something... 
    during do ... end 
    something else ... 
end 

私は、彼らがduringキーワードが含まれていません場合、異なるブロックを処理することにより、言語を簡素化したいと思います。この場合、他のRubyブロックと同じように扱うことができます。

ブロックに特定のメソッドが含まれているかどうかを検出することは可能ですかを実行しないでください。このメソッドは、ifまたはwhileステートメントのように、内部スコープ内にネストされていないと仮定するのは問題ありません。可能であれば、これは反射を含んでいると思います。これは大丈夫です。

洗練と説明

私は停止問題を解決したり、Rubyのハッカーが考えるかもしれない任意のトリックを克服しようとしていないのです。解決策は、最も素朴なケースにのみ適用される可能性があります。

いくつかの言語では、実行時にソースコードに反映させることができます。 Pythonのメソッドオブジェクトには、バインディングやバイトコードのようなフィールドがあります。 Javaでは、メソッドのバイトコードを読み込んでinvokevirtualコマンドを探すことは可能ですが、それほど簡単ではありません。

私はRubyにあまり慣れていません。私は、procsやブロックのようなコントロール要素を表すRubyオブジェクトにも同様のフィールドがあるのか​​どうかはわかりません。私の記憶が役立つなら、Rubyは実行時にASTにアクセスするためのフレームワークをいくつか持っています。しかし、このフレームワークが特定のブロックにアクセスできるかどうか、またそのフレームワークがどのよう単純なケースでのみ機能する実行時AST解析に基づくソリューションは、完全に受け入れられます。

答えて

0

IMOはあなた自身のためにこの方法の中からそうすることを余儀なくされています。それはメソッドを定義するかどうかによって異なりますが、必要に応じてメソッドをオーバーライドする方法はまだあります。自然発症頭に浮かぶ唯一の方法はsourcify宝石からto_source方法を使用して、結果の文字列に対してマッチングさ

+0

私はこれについて考えましたが、私のニーズを満たしていません。私はそれを実行する前にブロックのこのプロパティを検出する必要があります。 –

+0

あなたが達成しようとしているものについてもう少し具体的になるかもしれませんが、ブロックがブロック内で特定の機能を呼び出しているかどうかを検出することはできません。 –

2

このものの後半のAbit。これにより

x = proc do 
    something... 
    during do ... end 
    something else ... 
end 

x.to_source {|body| body =~ /\bduring\b\s*(\{|do)/m } 

を、uはS式を横断避けることができます。とにかく、sourcifyはPROC番号のto_source uはuが望むものを得るのを助けるために身体マッチャに渡してサポートしています。しかし、Proc#to_sexp & Proc#to_sourceによって返されたものは、ParseTreeと互換性があるように正規化されています。 uは本当に(。それは、もともと書かれているように、例えばコメントを保持)のソースを取得したい場合は、uが試すことができます。

x.to_raw_source {|body| body =~ /\bduring\b\s*(\{|do)/m } 

uは1.9固有のコードをお持ちの場合は、sourcifyは、フードの下として、それを破ることRubyParserを使用して構文チェックを行っています。& RubyParserは100%互換性のある1.9構文ではありません。しかし、この問題を解決するための継続的な作業があります。

希望します。]

+0

詳細をお寄せいただきありがとうございます。私は上記のto_sexpを書いているが、 –