119

2 つの質問があります

ベストプラクティス

  • パブリック インターフェイスを使用してデータ構造に対して何らかの操作を実行するアルゴリズムがあります。
  • 現在、これは多数の静的メソッドを持つモジュールであり、1 つのパブリック インターフェイス メソッドを除いてすべてプライベートです。
  • すべてのメソッド間で共有する必要があるインスタンス変数が 1 つあります。

これらは私が見ることができるオプションです。どれが最適ですか?:

  • 静的 (Ruby では「モジュール」) メソッドを持つモジュール
  • 静的メソッドを持つクラス
  • データ構造に含めるためのMixinモジュール
  • そのデータ構造を変更するアルゴリズムの部分 (非常に小さい) をリファクタリングし、アルゴリズム モジュールの静的メソッドを呼び出す mixin を作成します。

技術部

プライベート Module メソッドを作成する方法はありますか?

module Thing
  def self.pub; puts "Public method"; end
  private
  def self.priv; puts "Private method"; end
end

そこprivateには何の効果もないようですが、問題なく呼び出すことができますThing.priv

4

10 に答える 10

94

これを行うための最良の方法(およびほとんどの場合、既存のライブラリの作成方法)は、すべてのロジックを処理するモジュール内にクラスを作成することであり、モジュールは便利なメソッドを提供するだけだと思います。

module GTranslate
  class Translator
    def perform(text)
      translate(text)
    end

    private

    def translate(text)
      # do some private stuff here
    end
  end

  def self.translate(text)
    t = Translator.new
    t.perform(text)
  end
end
于 2009-01-08T15:11:19.257 に答える
83

Module.private_class_method間違いなく、より多くの意図を表現するもあります。

module Foo
  def self.included(base)
    base.instance_eval do
      def method_name
        # ...
      end
      private_class_method :method_name
    end
  end
end

質問のコードの場合:

module Thing
  def self.pub; puts "Public method"; end
  def self.priv; puts "Private method"; end
  private_class_method :priv
end

Ruby 2.1 以降:

module Thing
  def self.pub; puts "Public method"; end
  private_class_method def self.priv; puts "Private method"; end
end
于 2009-01-06T21:48:51.953 に答える
29

モジュールが混在しているときに、「included」メソッドを使用して、凝ったことを行うことができます。

module Foo
  def self.included(base)
    class << base 
      def public_method
        puts "public method"
      end
      def call_private
        private_method
      end
      private
      def private_method
        puts "private"
      end
    end
  end
end

class Bar
  include Foo
end

Bar.public_method

begin
  Bar.private_method
rescue
  puts "couldn't call private method"
end

Bar.call_private
于 2008-11-26T16:58:34.490 に答える
11

残念ながら、privateインスタンス メソッドにのみ適用されます。クラスでプライベートな「静的」メソッドを取得する一般的な方法は、次のようにすることです。

class << self
  private

  def foo()
   ....
  end
end

確かに、私はこれをモジュールで実行したことはありません。

于 2008-11-25T21:15:25.440 に答える
3

素敵な方法はこのようなものです

module MyModule
  class << self
    def public_method
      # you may call the private method here
      tmp = private_method
      :public
    end

    private def private_method
      :private
    end
  end
end

# calling from outside the module
puts MyModule::public_method
于 2015-06-15T20:21:16.613 に答える
1

クラス変数/定数内にラムダとしてメソッドを保存するのはどうですか?

module MyModule
  @@my_secret_method = lambda {
    # ...
  }
  # ...
end

テスト用:
UPD:6年後のこのコードの大幅な更新は、プライベートメソッドを宣言するためのよりクリーンな方法を示していますd

module A
  @@L = lambda{ "@@L" }
  def self.a ; @@L[] ; end
  def self.b ; a ; end

  class << self
    def c ; @@L[] ; end
    private
    def d ; @@L[] ; end
  end
  def self.e ; c ; end
  def self.f ; self.c ; end
  def self.g ; d ; end
  def self.h ; self.d ; end

  private
  def self.i ; @@L[] ; end
  class << self
    def j ; @@L[] ; end
  end

  public
  def self.k ; i ; end
  def self.l ; self.i ; end
  def self.m ; j ; end
  def self.n ; self.j ; end
end

for expr in %w{ A.a A.b A.c A.d A.e A.f A.g A.h A.i A.j A.k A.l A.m A.n }
  puts "#{expr} => #{begin ; eval expr ; rescue => e ; e ; end}"
end

ここで、次のことがわかります。

A.a => @@L
A.b => @@L
A.c => @@L
A.d => private method `d' called for A:Module
A.e => @@L
A.f => @@L
A.g => @@L
A.h => private method `d' called for A:Module
A.i => @@L
A.j => @@L
A.k => @@L
A.l => @@L
A.m => @@L
A.n => @@L

1)@@L外部からアクセスすることはできませんが、ほとんどどこからでもアクセスできます
2)class << self ; private ; defメソッドdを外部および内部からアクセスできないようにしますself.が、それなしではアクセスできません-これは奇妙です
3)メソッドをプライベートにしないprivate ; self.private ; class << selfください-両方にアクセスできますありとなしself.

于 2012-10-17T00:21:35.077 に答える
0

プライベート モジュールまたはクラスを作成する

定数はプライベートではありません。ただし、定数に割り当てずにモジュールまたはクラスを作成することは可能です。

その:private_class_methodため、プライベート モジュールまたはクラスを作成し、その上でパブリック メソッドを定義することもできます。

module PublicModule
  def self.do_stuff(input)
    @private_implementation.do_stuff(input)
  end

  @private_implementation = Module.new do
    def self.do_stuff(input)
      input.upcase # or call other methods on module
    end
  end
end

使用法:

PublicModule.do_stuff("whatever") # => "WHATEVER"

Module.newおよびClass.newのドキュメントを参照してください。

于 2016-11-10T15:56:24.867 に答える