8

Rubyクラス定義内でprivate/が記述されている場合、実際には何が起こっていますか?protectedこれらはキーワードではないため、メソッド呼び出しである必要がありますが、どこで定義されているかわかりません。それらは文書化されていないようです。private/protectedメソッド(以下に表示)を宣言する2つの異なる方法は、異なる方法で実装されていますか?(2番目の方法は明らかにメソッド呼び出しですが、これは最初の方法ではそれほど明白ではありません。)

class Foo
  private
  def i_am_private; end
  def so_am_i; end
end

class Foo
  def i_am_private; end
  def so_am_i; end
  private :i_am_private, :so_am_i
end
4

2 に答える 2

9

どちらもメソッド呼び出しです。ドキュメントからの引用:

各関数は、2つの異なる方法で使用できます。

  1. 引数なしで使用すると、3つの関数は、後で定義されるメソッドのデフォルトのアクセス制御を設定します。
  2. 関数は引数を使用して、名前付きメソッドと定数のアクセス制御を設定します。

こちらのドキュメントを参照してください:

  1. Module.private
  2. アクセス制御

あなたはその方法がどのように生まれるかを探していましたModule.privateここでそれが起こります。そして、ここにそれについてのいくつかのより多くの情報があります。rb_define_private_methodで定義されているものから始めて、さらに詳しく読む必要がありますclass.c

お役に立てば幸いです。

于 2011-11-05T20:24:43.333 に答える
0

彼らのキーワードのような振る舞いについて何かを付け加えたいと思います。なぜなら、答えは方法よりも場所に関するものだったからです。その答えは、Rubyの複雑なメタプログラミング機能にあります。フックを利用してキーワードとして使用することができます。Rubyのフックは、特定のイベント(つまりフックの名前)が発生したときに呼び出される関数です。重要なのは、フックが引数として定義されたメソッドの名前を受け取ることです。このようにして、フックの動作を変更することができます。method_addedmethod_added

たとえば、このフックを使用して、Pythonのデコレータと同様の動作を定義できます。private重要な部分は、 andメソッドとは異なりprotected、このデコレータのようなメソッドは、method_addedそれ自体を定義しないaを定義する必要があるということです。

class Module
  def simple_decorator
    eigenclass = class << self; self; end
    eigenclass.class_eval do
      define_method :method_added do |name|
        eigenclass.class_eval { remove_method :method_added }
        old_name = 'old_' + name.to_s
        alias_method old_name, name
        class_eval %Q{
          def #{name}(*args, &block)
            p 'Do something before call...'
            #{old_name}(*args, &block)
            p '... and something after call.'
          end
        }
      end
    end
  end
end

class UsefulClass
  simple_decorator
  def print_something
    p "I'm a decorated method :)"
  end

  def print_something_else
    p "I'm not decorated :("
  end
end

a = UsefulClass.new
a.print_something
a.print_something_else

simple_decorator言語キーワードのように見え、private;のように動作します。ただし、method_addedフックが削除されるため、直後のメソッド定義にのみ適用されます。

于 2012-05-02T15:18:47.333 に答える