2017-01-14 2 views
1

私のコードを静的に解析できるようにしたい。つまり、すべての関数と変数が入っているファイルのプレーンテキストから知ることです。 IDEやテキストエディタプラグインは、すべてのシンボルの起源をトレースすることができれば、より効果的です。私はこのようなアプリケーションコードがある場合Rubyにサブモジュールやクラスを明示的に含めることは可能ですか?

だから、たとえば、:

#... 
Y.some_method() 
#... 

をそれから私は、どこかのページに含ま/インポート/必要/拡張/ DEF文でYを見てみたいです。

私が使用する他の言語では、名前空間のどの部分を現在のコンテキストに持ち込むかを明示的に選択できます。

from X import Y 

ハスケル:

import X (Y) 

エリクサー:

alias X.Y, as: Y 

そして、それはイムすることが可能ですしばらくのPython

from X import * 

」:ポートすべては、Python、 "ワイルドカードのインポート" is frowned uponに名前を含んでいました。 。 。彼らは読者と多くの自動化ツールの両方を混乱させ、名前空間に存在する名前それが不明確にします。ワイルドカード 『のように持って来るために唯一の方法である」

をRubyでは、この完全に暗黙のようです』含ま名前:

include X 

これはY利用できるようになりますが、これを明示的にいくつかの方法がありdocs for Ruby includeは、任意のオプションを示していない私は本当にRubyでやってみたい何

が何かあります?。 1つのようにこれらのF:

from X include Y 
include X::Y as Y 

私がこれまでに作ってみた最高のは、次のとおりです。

require 'x/y' ; Y = X::Y 

はここでこれを可能にする別の質問への答えでa crazy hackです。

+4

のファイルの場所とソースコードを印刷しますここのRubyのすべての言語には独自のスタイルがあり、Rubyは常にフォーマル性よりも利便性に傾いています。 Rubyはコードのあらゆる部分が貢献する単一のグローバルな名前空間を持っているので、何かがどこから来たのかを特定することは必ずしも実用的ではありません。 *ローマの時*の原則がここに当てはまります:RubyをやっているときにRubyのやり方をしてください。 PythonやNode.jsではそうです。穀物に向かうのは、Pythonのように動作するRubyの奇妙な方言のように、あなたがいかに不自然で、維持できないコードを作成するかです。 – tadman

+0

@tadmanメソッド呼び出しのように見えるシンボルが表示され、それを変更したいときはどうしますか?私の場合、それは 'log(...)'でした。それは私の方法であったかもしれませんが、それは標準的な図書館のものだったかもしれません、それはいくつかの宝石から来たかもしれません...私は古いコードに戻っていました、 dはコードがどこから来ているかを少なくとも知っています。 ? – Dogweather

+2

@Dogweather:Ruby: 'method(:log).owner'に尋ねることができます。ところで、あなたは 'include'が何をするのかについて基本的な誤解を持っているようです。特に、あなたはそれがいくつかのモジュールシステムの一部だと考えるようです。そうではない。これはRubyのmixinシステムの一部です。言い換えれば、すべての 'クラスC; 'M''を含む' 'C''のスーパークラスを作成します。 –

答えて

2

これを試してください。しかし、私はあなたがRubyのやり方でそれをやってみるべきだと私は@ tadmanに同意します。

Object.define_singleton_method(:include) do |*mths, from: nil| 
    mod = from || mths.first 
    mod = mod.dup 

    if from 
    all_mths = mod.instance_methods 
    (all_mths - mths).each { |mth| mod.send :undef_method, mth } 
    end 

    super(mod) 
end 

module Foobar 
    def foo 
    puts :foo 
    end 

    def bar 
    puts :bar 
    end 
end 

class Abc 
    include Foobar 
end 

Abc.new.foo # => 'foo' 
Abc.new.bar # => 'foo' 

class AbcWithoutBar 
    include :foo, from: Foobar 
end 

AbcWithoutBar.new.foo # => 'foo' 
AbcWithoutBar.new.bar # => NoMethodError 
+0

これはとてもクールです。私は、 'include'メソッドを' include'メソッドを呼び出して実行する方法を試してきました。 – Dogweather

+0

@Dogweatherそれは 'include'をオーバーライドするよりも良い考えです。imho –

2

Rubyはいつもあなたrequire

、ファイルの部分的な実行がrequire部分があることはできませんがないので、コードを実行します。

あなたrequire機能Rubyは$:に荷重経路を使用して、対応するファイルを見つけ、ロードされたファイルのリストに対して二重のチェック$"で、ファイルがまだロードされていない場合は、ファイルを実行します。

Rubyは動的言語です。Rubyはソースコードを推論する最も良い方法は、静的ではなく実行中のプログラムを停止することです。実際にはclassdefでさえ、宣言ではなく、実行時に実行されるメソッド呼び出しです。あなたがメソッドやクラスは最高使用pryが定義されている場所を知りたい場合は

class Surprise < [Array, Hash, Fixnum, Object].sample 
end 

例えば、この不自然な例を考えてみましょう。 pryが必要な場合は、binding.pryを使用してソースコードのどこかで停止し、オブジェクトやソースコードを検査することができます。最も便利なコマンドの二つはls$

  • lsプリントオブジェクトまたはクラス
  • $のすべてのメソッドですあなたは多くのことを求めている方法
+0

私が望むのは、部分的な' include'です。 – Dogweather

+0

'$'についてのお返事ありがとうございます – Dogweather

+1

おそらく "洗練"を見てください。レキシカルスコープのものです。 – akuhn

関連する問題