0

私のプロジェクトBarには、このクラスFooがあり、そのインスタンスは一意の名前付きの現実世界のオブジェクトを表します。これらのインスタンスへの参照は、私のプロジェクトのデータ構造の周りに細心の注意を払って散らばっていますが、名前でアクセスできるようにすることも決定しました。この目的のために、クラス Foo 自体がそのインスタンスをトレースします。

module Bar
  class Foo
    attr_reader :name

    def initialize( name )
      @name = name
    end

    def self.new *args, &block
      new_instance = super
      n_i_name = new_instance.name
      ( @instances ||= {} ).merge! new_instance => n_i_name
      return new_instance
    end

    def inspect; "Foo instance #{name}" end
  end
end

今ではよくあるパターンです。通常、インスタンスにアクセスするには、次のようにパブリック クラス メソッドを確立しますFoo

class << Bar::Foo
  def instance( i )
    case i
    when self then i
    else @instances.rassoc( i ).first end
  end
end

i = Bar::Foo.new "John Smith"
#=> Foo instance John Smith
i.object_id
#=> 68997470
Bar::Foo.instance( "John Smith" ).object_id
#=> 68997470

しかし、問題は、Barモジュールの下に名前付きインスタンスを持つ類推クラス ( など) がありBar::Baz、インスタンスや相互に名前でBar::Quuxアクセスする必要があることです。Fooしたがって、これらのさまざまなクラスが名前で他のインスタンスにアクセスする方法の順序を維持することは、Barモジュール自体の責任であると考え、その中にパブリック モジュール メソッドを作成しました。

module Bar
  # Foo method blah blah blah...
  def self.Foo( i ); Foo.instance i end

  # Baz method blah blah blah...
  def self.Baz( i ); Baz.instance i end

  # Quux method blah blah blah...
  def self.Quux( i ); Quux.instance i end
end

クラスFooBazQuuxが互いに参照するときはいつでも、Bar.Foo( "John Smith" )スタイル呼び出しを使用します。これにより、これらのインスタンスを一意の名前で参照することも可能になります。さて、私の問題は、これがまだ 100% コーシャとは思えないことです。rdocモジュールのドキュメントを作成するために実行するとBar、パブリック クラス メソッド#Foo#Baz、ドキュメントに作成され#Quuxます。しかし、これらは実際にはユーザー インターフェイスの一部になることを意図したものではありません。したがって、次のオプションがありますが、それぞれに問題があります。

  1. #Foo#Baz#Quuxをユーザー インターフェイスに含めます。問題: ユーザーは実際にはそれほど必要としていません。それらを UI に含めることは、私の設計意図ではありませんでした。

  2. # :nodoc:それらにディレクティブを追加して、それらをrdoc文書化しないようにします。問題: 気分が悪い。Bar.Foo友達がユーザーインターフェイスから除外されたようなものではありません。それらはまだUIの一部のように感じますが、文書化されておらず、秘密です. 私はそれをしたくありません。

  3. を使用してそれらをプライベートに宣言します#private_class_method。ただし、インスタンス#Foo#Baz#Quuxが通常の操作中に名前で相互にアクセスする場合でも、それらもBar.send :Foo, "John Smith"スタイルを使用する必要があります。

質問: オプション 3. が最も害が少ないようです。しかし、それでも完璧ではありません。理想的には、メソッドBar.FooBar.Baz、を保護して、ユーザーが を使用する必要があるときに、 をBar.Quux呼び出すだけでこれらの人が名前で相互に呼び出すことができるようにしたいと考えています。これらのモジュール メソッドはユーザー向けに文書化されていません。この状況を達成するために、他にどのようなオプションが必要ですか? 一部のクラスが他の誰かのプライベート メソッドを自由に使用できるようにする方法はありますか? また、保護されたクラス メソッドの経験がありませんが、解決策になるでしょうか? これを読んでくれてありがとう。Bar.Foo "John Smith"Bar.send :Foo, "John Smith"

4

1 に答える 1

1

Understanding private Methods in Rubyを見て、SO で private/protected を検索してください。読むべき資料がたくさんあります。

保護されたクラス メソッド:

class Foo
    class << self
        def prot
            puts "self.prot"
        end
        protected :prot
    end
...

Bar::Foo.prot #=> protected method `prot' called for Bar::Foo:Class (NoMethodError)
于 2012-12-09T06:33:50.587 に答える