私のプロジェクト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
クラスFoo
、Baz
、Quux
が互いに参照するときはいつでも、Bar.Foo( "John Smith" )
スタイル呼び出しを使用します。これにより、これらのインスタンスを一意の名前で参照することも可能になります。さて、私の問題は、これがまだ 100% コーシャとは思えないことです。rdoc
モジュールのドキュメントを作成するために実行するとBar
、パブリック クラス メソッド#Foo
、#Baz
、ドキュメントに作成され#Quux
ます。しかし、これらは実際にはユーザー インターフェイスの一部になることを意図したものではありません。したがって、次のオプションがありますが、それぞれに問題があります。
#Foo
、#Baz
、#Quux
をユーザー インターフェイスに含めます。問題: ユーザーは実際にはそれほど必要としていません。それらを UI に含めることは、私の設計意図ではありませんでした。# :nodoc:
それらにディレクティブを追加して、それらをrdoc
文書化しないようにします。問題: 気分が悪い。Bar.Foo
友達がユーザーインターフェイスから除外されたようなものではありません。それらはまだUIの一部のように感じますが、文書化されておらず、秘密です. 私はそれをしたくありません。を使用してそれらをプライベートに宣言します
#private_class_method
。ただし、インスタンス#Foo
、#Baz
、#Quux
が通常の操作中に名前で相互にアクセスする場合でも、それらもBar.send :Foo, "John Smith"
スタイルを使用する必要があります。
質問: オプション 3. が最も害が少ないようです。しかし、それでも完璧ではありません。理想的には、メソッドBar.Foo
、Bar.Baz
、を保護して、ユーザーが を使用する必要があるときに、 をBar.Quux
呼び出すだけでこれらの人が名前で相互に呼び出すことができるようにしたいと考えています。これらのモジュール メソッドはユーザー向けに文書化されていません。この状況を達成するために、他にどのようなオプションが必要ですか? 一部のクラスが他の誰かのプライベート メソッドを自由に使用できるようにする方法はありますか? また、保護されたクラス メソッドの経験がありませんが、解決策になるでしょうか? これを読んでくれてありがとう。Bar.Foo "John Smith"
Bar.send :Foo, "John Smith"