在我的 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
是 gem 中的一个类,其功能与我想要的一个类几乎相同。Foo
事实上,我想要的和我想要的唯一区别是那个讨厌的HELLO
常数。我想MyClass.say_hello
回复“你好,鲍勃!” 而不是“你好,世界!”。(在你建议只是覆盖之前say_hello
,在我的例子中 Foo 有很多其他方法可以使用HELLO
,并且say_hello
比我的例子中复杂得多。)
现在我可以更改Foo::HELLO
为Foo::HELLO.slice!(0, 7) << "Bob!"
,但这会改变我不想要的 gem 的行为。那么我将如何创建一个Foo
具有不同值的精确副本HELLO
呢?
TLDR: Foo 是 gem 的一部分,所以我不想编辑源代码。我想要一个行为与 Foo 完全相同的类,除了HELLO
设置为不同的值。