web-dev-qa-db-ja.com

Rubyプライベートメソッドを呼び出す静的メソッドを持つクラス?

多くの静的メソッドを持つクラスがあります。それぞれが共通のメソッドを呼び出す必要がありますが、私はこの後者のメソッドを公開しないようにしています。それをプライベートにすると、クラスの独自のインスタンスからのアクセスのみが許可されますか? Protectedは、ここでも問題を解決するようには見えません。

Do_calcを静的コンテキストで外部から呼び出されないようにするにはどうすればよいですか? (最初の2つの静的メソッドから呼び出せるようにしておく。)

class Foo
  def self.bar
    do_calc()
  end
  def self.baz
    do_calc()
  end
  def self.do_calc
  end
end
28
yamori

まず、staticRuby専門用語の一部ではありません。

簡単な例を見てみましょう:

class Bar
  def self.foo
  end
end

これは、明示的なオブジェクトfooでメソッドselfを定義します。このスコープでは、包含オブジェクトBarを返します。はい、それはクラスメソッドと定義できますが、Rubyでは静的は実際には意味がありません。

その場合、privateは機能しません。明示的なオブジェクトでメソッドを定義しているためです(例:def self.foo)アクセス修飾子をバイパスし、メソッドをパブリックにします。

あなたができることは、class << self構文を使用して、包含クラスのメタクラスを開くを作成し、そこでメソッドをインスタンスメソッドとして定義します。

class Foo
  class << self

    def bar
      do_calc
    end

    def baz
      do_calc
    end

    private

    def do_calc
      puts "calculating..."
    end
  end
end

これにより、必要なものが得られます。

Foo.bar
calculating...

Foo.baz
calculating...

Foo.do_calc
NoMethodError: private method `do_calc' called for Foo:Class
43
tompave

次のように、- private_class_method を使用してプライベートクラスメソッドを定義できます。

class Foo
  def self.bar
    do_calc
  end

  def self.baz
    do_calc
  end

  def self.do_calc
    #...
  end
  private_class_method :do_calc
end
14
spickermann

またはRuby 2.1以降:

class Foo
  def self.bar
    do_calc
  end

  private_class_method def self.do_calc
    #...
  end
end
1
mb21