Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

Rubyでの静的分析

ソースコードを解析して、すべてのメソッド、それらが定義されている場所、およびそれらが取る引数を見つけたいとします。

どうすればこれができますか?

あなたの最初のアイデアはそれのために正規表現を書くことかもしれません…

しかし、もっと良い方法はありますか?

Rubyでの静的分析

はい!

静的分析 は、ソースコード自体から情報を抽出する必要がある場合に使用できる手法です。

これは、ソースコードをトークンに変換する(解析する)ことによって行われます。

さっそく始めましょう!

パーサージェムの使用

Rubyには標準ライブラリで利用可能なパーサーがあります。名前はRipperです。出力を操作するのは難しいので、私は素晴らしいパーサーgemを使用することを好みます。 Rubocopはこの宝石を使って魔法をかけます。

このgemには、コードを直接解析して結果の解析ツリーを確認するために使用できるバイナリも含まれています。

ここに例があります

ruby-parse -e '%w(hello world).map { |c| c.upcase }'

出力は次のようになります:

(block
  (send
    (array
      (str "hello")
      (str "world")) :map)
  (args
    (arg :c))
  (send
    (lvar :c) :upcase))

これは、Rubyがコードを解析する方法を理解しようとしている場合に役立ちます。ただし、独自の分析ツールを作成する場合は、ソースファイルを読み取り、解析してから、生成されたツリーをトラバースする必要があります。

require 'parser/current'

code = File.read('app.rb')
parsed_code = Parser::CurrentRuby.parse(code)

パーサーは、コードのAST(抽象構文木)を返します。名前にあまり恐れないでください。思ったよりもシンプルです🙂

ASTのトラバース

これで、パーサーを使用してコードを解析しました。 結果のASTをトラバースする必要がある宝石。

これを行うには、 AST ::Processorから継承するクラスを作成します。 。

class Processor < AST::Processor
end

次に、このクラスをインスタンス化して、 .processを呼び出す必要があります 方法:

ast = Processor.new
ast.process(parsed_code)

on _を定義する必要があります メソッド。これらのメソッドは、ASTのノード名に対応しています。

定義する必要のあるメソッドを見つけるには、 handler_missingを追加します。 Processorクラスへのメソッド。 on_beginも必要です メソッド。

class Processor < AST::Processor
  def on_begin(node)
    node.children.each { |c| process(c) }
  end

  def handler_missing(node)
    puts "missing #{node.type}"
  end
end

ここに私たちがいます

Ruby ASTと基本的なプロセッサがあります。このコードを実行すると、ASTのノードタイプが表示されます。

すべてのon_を実装する必要があります 使用したいメソッド。たとえば、すべてのインスタンスメソッド名とその行番号が必要な場合は、次のように実行できます。

def on_def(node)
  line_num    = node.loc.line
  method_name = node.children[0]

  puts "Found #{method_name} at line #{line_num}"
end
を配置します。

プログラムを実行すると、見つかったすべてのメソッド名が出力されます。

結論

Ruby静的分析ツールの構築は、見た目ほど難しくはありません。より完全な例が必要な場合は、私のclass_indexergemを見てください。今度はあなた自身のツールを作る番です!

この投稿を共有してください あなたがそれを楽しんだなら! 🙂


  1. Ruby NLP:楽しさと利益のためのNグラム分析

    大量のテキストのコレクションが与えられ、そこから何らかの意味を抽出したい場合はどうしますか? 良いスタートは、テキストをn-gramsに分割することです。 。 ここに説明があります : 計算言語学と確率の分野では、n-gramは、テキストの特定のシーケンスからのn個のアイテムの連続したシーケンスです。 –ウィキペディア 例 : 「こんにちは、お元気ですか?」というフレーズをとると、その場合、ユニグラム(1つの要素のngram)は次のようになります:Hello, there, how, are, you 、およびバイグラム(2つの要素のngram):[Hello, there],

  2. Rubyでの静的分析

    ソースコードを解析して、すべてのメソッド、それらが定義されている場所、およびそれらが取る引数を見つけたいとします。 どうすればこれができますか? あなたの最初のアイデアはそれのために正規表現を書くことかもしれません… しかし、もっと良い方法はありますか? はい! 静的分析 は、ソースコード自体から情報を抽出する必要がある場合に使用できる手法です。 これは、ソースコードをトークンに変換する(解析する)ことによって行われます。 さっそく始めましょう! パーサージェムの使用 Rubyには標準ライブラリで利用可能なパーサーがあります。名前はRipperです。出力を操作するのは難し