2012-07-24 14 views
6

Rubyでは、私の理解では、selfは裸のメソッド呼び出しの暗黙の受信者です。ただし、`self`が常にRubyの暗黙の受信機である場合、なぜ` self.puts`は動作しませんか?

~: irb 
>> puts "foo" 
foo 
=> nil 
>> self.puts "foo" 
NoMethodError: private method `puts' called for main:Object 

これについて説明しますか? selfは、ユーザーが明示的に指定していない暗黙の受信機であることを

>> method(:puts).owner 
=> Kernel 
+1

try 'self.send:puts、" foo "' sendを使ってプライベートメソッドを呼び出すことができます。 – DGM

答えて

8

プライベートメソッドは、私は答えはこれだと思いレシーバ

を持つことはできません。

例:

class Baker 
    def bake_cake 
    make_batter 
    self.use_oven # will explode: called with explicit receiver 'self' 
    end 

    private 
    def make_batter 
    puts "making batter!" 
    end 

    def use_oven 
    puts "using oven!" 
    end 

end 

b = Baker.new 
b.bake_cake 

明示的な受信機が存在しないことができるので、あなたは確かにb.use_ovenを行うことはできません。それがメソッドのプライバシーを強化する方法です。

+0

しかしputsはパブリックメソッド、メソッド(:puts).owner.public_methods.grep/puts/returns [:puts]です。 MRI ruby​​ 1.93p194 – dfang

+0

申し訳ありませんが、私はメソッドの検索を忘れていました。 self.class.ancestors => [Object、Kernel、BasicObject] – dfang

+0

@dfang - 子クラスによってプライベートとして再分類されている可能性がありますか? –

3

あなたが正しいです:

はケースでは、任意のヘルプです。 self.putsを許可されていない理由は、(受信者がselfであっても)明示的な受信者でプライベートメソッドを呼び出すことができず、エラーメッセージにはputsがプライベートメソッドであるためです。

1

ruby​​では、self.の構文を使用してプライベートメソッドにアクセスすることはできません。また、一般的には受信者(.の前にあるもの)を使用してプライベートメソッドにアクセスすることはできません。これは保護されたメソッドに対してのみ可能です。メソッドのプライバシーを強制するRubyの方法は、それが明示的な受信機とのプライベートメソッドを呼び出すことはできませんということです。

4

これはRubyのプライバシーの定義なので、プライベートメソッドは暗黙的な受信者でのみ呼び出すことができます。

実際には、この規則の例外があります:foo = bar常には、ローカル変数を作成しますので、そうでなければ、すべてのでそれらを呼び出すことはできませんので、あなたは(なし、self.foo = barのような民間のセッターを呼び出すことが許可されています反射を使用して)。

+1

+1は例外を表示します。 –

+0

リフレクションを使用するだけでなく、 'self'を使わずに' foo =(bar) 'を実行することもできます。 –

+1

@AndrewGrimm:うまくいきません、ちょっと試しました。また、括弧は式のグループ化に使用できるので、完全に有効なローカル変数の割り当てであるため、機能しないということも意味があります。 –

関連する問題