def class A
def a
raise "hi" #can't be reached
end
class B
def b
a() #doesn't find method a.
end
end
end
私はbからaを呼び出して例外を発生させたいと思います。どうやって?ネストされたクラスは、Rubyの外部クラスのメソッドにどのようにアクセスできますか?
def class A
def a
raise "hi" #can't be reached
end
class B
def b
a() #doesn't find method a.
end
end
end
私はbからaを呼び出して例外を発生させたいと思います。どうやって?ネストされたクラスは、Rubyの外部クラスのメソッドにどのようにアクセスできますか?
Rubyにはネストされたクラスがありません。
動作を継承する唯一の方法は、まあ、継承によるものです。
コードを機能させるには、ネストされたクラスをサポートする言語を使用する必要があります。
私は他の何かを知りません。
Javaにはネストされたクラスと呼ばれる構造がありますが、デザインにはいくつか不都合な制限があります。
は、上記のあなたの例では、それはA
内にネストされクラスB
ではありません、それはA
内にネストされているB
一定です。このことについて考える:A::B
とC
:
C = A::B
さて、クラスが名で入手可能です。 C
がグローバルであり、A
の内部にネストされていないことがすぐに分かるはずです。 (実際には、C
はObject
の中に入れ子になっていますが、実際にはグローバル定数もないので、それはポイントの横にあります)。C
とA::B
は同じクラスなので、入れ子にすることも入れ子にすることもできません。唯一の論理的な結論は、クラス自体がネストされていないことです。
ネストされたクラスの定義上の特徴は、メソッドルックアップが継承チェーンの上とネストの外側の2つの次元に沿って進むことです。 Rubyは、すべてのOO言語の99.9%と同様、前者をサポートしています。 (ある意味では、ネストされたクラスはスーパークラスの機能だけでなく、その周囲のクラスの機能も継承します。)
清算コメント+1を私に教えていただきありがとうございます。 –
@Michael Kohl:これらはネストされたクラスではなく、名前空間の定数です。最初の文はそれを正しく得ます。私が思うには、2番目の文章はもともと「クラスを参照している入れ子定数」のようなものを読み、少し強制的に聞こえると思ったので、間違ったことを気にせずに「入れ子クラス」に短縮しました。 Rubyにはクラスメソッドはありませんが、クラスオブジェクトのシングルトンクラスのインスタンスメソッドが正しく組み合わされているため、「クラスメソッド」と呼ばれています。残念ながら、この –
...ショートカット専門用語のようなものは、外部者や初心者のための重大な混乱につながる可能性があります。 StackOverflowのすべての質問を見て、 "普通のメソッドでX(嘲笑、オーバーライド、上書き、エイリアシング、ラッピング、スタブ)をする方法を知っていますが、クラスメソッドでどうやったらいいですか?私たちが使っているショートカットの専門用語のために、彼らはクラスメソッド*のようなものがないので、彼らは実際に自分の質問に対する答えを実際に知っていることを知らない。 –
a
は、クラスA
のクラスメソッドとしましたか?
class A
def self.a
raise "hi"
end
class B
def b
A::a
end
end
end
A::B.new.b
あなたはインスタンスメソッドとしてそれを維持したい場合は、明らかに例A.new.a
のためのように、インスタンス上でそれを呼び出す必要があります。
いいえ、私は本当に内部クラス、Newspeakスタイルを意味しました。 – nes1983
これは単なるlulzのためです:
class A
def a
puts "hello from a"
end
class B
def b
Module.nesting[1].new.a()
end
end
end
これは、全体がモジュール内にある場合にのみ機能します。 –
あなたは、ネストされたクラスは、その後そう、外側のクラスを拡張したい場合:
class Outer
class Inner < Outer
def use_outer_method
outer_method("hi mom!")
end
end
def outer_method(foo)
puts foo
end
end
foo = Outer::Inner.new
foo.use_outer_method #<= "hi mom"
foo.outer_method("hi dad!") #<= "hi dad"
は、私は通常、このような何かを:
class A
def a
puts "hi"
end
def createB
B.new self
end
class B
def initialize(parent)
@parent=parent
end
def b
@parent.a
end
end
end
A.new.createB.b
あなたの状況によっては、実際には解決策がありますが、かなり簡単です。 Rubyでは、オブジェクトが捕捉していないメソッド呼び出しを捕まえることができます。あなたが得る
A::B.new().b
:あなたがこれを行う場合
def class A
def a
raise "hi" #can't be reached
end
class B
def initialize()
@parent = A.new
end
def b
a() #does find method a.
end
def method_missing(*args)
if @parent.respond_to?(method)
@parent.send(*args)
else
super
end
end
end
end
をそれでは:だからあなたの例のためにあなたができる
!! #<RuntimeError: hi>
をそれはおそらくのようなものを作るための簡単な方法でありますSubControllerは特定のアクティビティのみを処理しますが、基本的なコントローラメソッドを簡単に呼び出すことができます(親コントローラをイニシャライザの引数として送信することもできます)。
明らかに、これは控えめに使用する必要があります。実際に使用すると混乱する可能性がありますが、コードを単純化するのは本当に素晴らしいことです。
'B'は' A'を継承しますか? – adamax