私のRubyアプリケーションでは、元のクラスに影響を与えずにクローンに若干の変更を加えることができるように、クラスのクローンを作成したいと思います(詳細については以下の注を参照してください)。残念ながら、複製されたクラスは私が期待するように動作していません。具体的には、複製されたクラスのクラスメソッドは、定数とクラス変数にアクセスするのに問題があるようです。観察:
irb(main):001:0> class Foo
irb(main):002:1> HELLO = "Hello, world!"
irb(main):003:1> def self.say_hello
irb(main):004:2> HELLO
irb(main):005:2> end
irb(main):006:1> def self.cls_var=(val)
irb(main):007:2> @@cls_var = val
irb(main):008:2> end
irb(main):009:1> def self.cls_var
irb(main):010:2> @@cls_var
irb(main):011:2> end
irb(main):012:1> end
=> nil
irb(main):013:0> Foo.say_hello
=> "Hello, world!"
irb(main):014:0> Foo.cls_var = "Test"
=> "Test"
irb(main):015:0> Foo.cls_var
=> "Test"
irb(main):016:0> Bar = Foo.clone
=> Bar
irb(main):017:0> Bar.say_hello
NameError: uninitialized constant Class::HELLO # ???
from (irb):4:in `say_hello`
from (irb):17
from C:/Ruby193/bin/irb:12:in `<main>`
irb(main):018:0> Bar.cls_var = "Another test"
(irb):7: warning: class variable access from toplevel # Say what?
=> "Another test"
irb(main):019:0> Bar.cls_var
(irb):10: warning: class variable access from toplevel
=> "Another test"
irb(main):020:0> Foo.cls_var
=> "Another test" # Why???
ここで何が起こっているのでしょうか。また、クローンを作成した後、BarがFooとまったく同じように機能するように、これを修正するにはどうすればよいですか。
注:この質問は、Rubyのフォローアップです。継承されたメソッドが古い定数ではなく新しい定数を使用するように、サブクラスの定数を「オーバーライド」する方法はありますか?
更新:申し訳ありませんが、なぜこれをやりたいのかはっきりしていなかったと思います。したがって、私の場合Foo
は、クラスの1つに必要な機能とほぼ同じ機能を持つgemのクラスです。Foo
実際、私が欲しいものとの唯一の違いは、その厄介なHELLO
定数です。MyClass.say_hello
「こんにちは、ボブ!」を返したいです。「Hello、World!」の代わりに。(そして、オーバーライドすることを提案する前にsay_hello
、私の場合、Fooには他にも多くのメソッドがHELLO
ありsay_hello
、私の例よりもはるかに複雑です。)
今、私はで変更Foo::HELLO
することができますFoo::HELLO.slice!(0, 7) << "Bob!"
が、それは私が望まない宝石の振る舞いを変更します。Foo
では、の値が異なる正確な複製を作成するにはどうすればよいでしょうHELLO
か。
TLDR: Fooはgemの一部なので、ソースを編集したくありません。HELLO
別の値に設定されていることを除いて、Fooとまったく同じように動作するクラスが必要です。