2017-03-28 5 views
2

RubyのOOPについてのほとんどすべてのリソースは、アクセス修飾子(キーワードpublicprivate、)の存在を示し、それらを正しく使用する方法を示しています。これらの修飾子がではなくキーワードであることを説明する程度は少なくなりますが、実際のメソッドであり、これらを呼び出すことで、この特定のクラスで将来定義されるすべてのメソッドの可視性が変更されます。しかし、私はについてどのような情報も見つけられませんでした。彼らは実際にそうしました。特殊な内部変数を変更するのか、現在のスコープ/バインディングのプロパティを変更するのか、あるいは特定のインタプリタフラグを設定するのか、それとも何か?"public"、 "private"および "protected"メソッドは何を*正確に*行いますか?

私は自分自身で少しの研究をしましたが、私は以前よりずっと混乱しました。次のコードスニペットを考えてみましょう:

class Test 
    public 
    define_method :public_define_method do 
     puts 'Public define_method' 
    end 

    private 
    define_method :private_define_method do 
     puts 'Private define_method' 
    end 

    public 
    def public_def 
     puts 'Public def' 
    end 

    private 
    def private_def 
     puts 'Private def' 
    end 
end 

t = Test.new 

t.public_define_method 
t.private_define_method 
t.public_def 
t.private_def 

#Output: 
#> Public define_method 
#> Private define_method 
#> Public def 
#> sandbox.rb:29:in `<main>': private method `private_def' called for #<Test:0x00000001cdfd38> (NoMethodError) 

私は常に新しい変数の可視性のスコープを作成するための追加的な癖を持つdefine_methodのための最適化された糖衣構文の一種としてdefと思ったが、明らかに、それによりがあるように思われます - defで作成されたメソッドはprivate/public修飾子の影響を受けますが、define_methodで作成されたメソッドは影響を受けません。さらに、define_methoddoesn't haveメソッドの可視性の変更に関連する引数については、その情報がメソッド自体ではなくクラスに格納されなければならないという結論に至りました。そのため、アクセス修飾子でフラグを設定する必要があります。しかし、なぜdefdefine_methodとは違うのですか?バックグラウンドではどうなりますか?アクセス修飾子メソッドで設定されたフラグをチェックし、クラスのプライベート/プロテクトメソッドの特別な隠しレジスタに自身を追加しますか?

要するに、私は非常に混乱しています。問題を明らかにする。前もって感謝します!

答えて

1

正確には?引数なしで公共 http://apidock.com/ruby/Module/public

は、公衆に続いて定義されたメソッドのデフォルトの可視性を設定します。引数を使用して、名前付きメソッドをpublic可視性に設定します。

出典:引数なしでhttp://apidock.com/ruby/Module/private

static VALUE 
rb_mod_public(int argc, VALUE *argv, VALUE module) 
{ 
    secure_visibility(module); 
    if (argc == 0) { 
     SCOPE_SET(NOEX_PUBLIC); 
    } 
    else { 
     set_method_visibility(module, argc, argv, NOEX_PUBLIC); 
    } 
    return module; 
} 

プライベートでは、民間へのその後 定義されたメソッドのデフォルトの可視性を設定します。引数を使用すると、指定されたメソッドを にプライベートな可視性を持つように設定します。

出典:

static VALUE 
rb_mod_private(int argc, VALUE *argv, VALUE module) 
{ 
    secure_visibility(module); 
    if (argc == 0) { 
     SCOPE_SET(NOEX_PRIVATE); 
    } 
    else { 
     set_method_visibility(module, argc, argv, NOEX_PRIVATE); 
    } 
    return module; 
} 

は、引数なしでhttp://apidock.com/ruby/Module/protected

を保護し、保護に続いて 定義されたメソッドのデフォルトの可視性を設定します。引数を使用して、名前付きメソッド に保護された可視性を設定します。

ソース

static VALUE 
rb_mod_protected(int argc, VALUE *argv, VALUE module) 
{ 
    secure_visibility(module); 
    if (argc == 0) { 
     SCOPE_SET(NOEX_PROTECTED); 
    } 
    else { 
     set_method_visibility(module, argc, argv, NOEX_PROTECTED); 
    } 
    return module; 
} 

これは本当にしかし、この情報の実際のアプリケーションでは役立ちません。 What are the differences between "private", "public", and "protected methods"?Why does Ruby have both private and protected methods?のような質問については、より現実的な情報を見つけることができます。

+0

ありがとうございますが、私が探しているものではありません。私はすでにRubyのカプセル化がどのように機能しているのか、これらのメソッドを呼び出す結果を知っています。質問を再読してください。私はC++についてよく知らないので、インタプリタのソースコードを自分で掘り起こすだけでもっと混乱が起こります。コードスニペットは本当に助けになりますが、 'SCOPE_SET'と' set_method_visibility'が何をするかについてもっと詳しく説明できますか?純粋なRubyで 'public' /' protected'/'private'の効果を再現するか、あるいはハードコーディングしていますか?ありがとう! – DeFazer

関連する問題