Ruby:在父类及其子类之间共享一个类变量

时间:2015-03-10 10:55:18

标签: ruby inheritance class-variables

我试图按照我在标题中描述的那样做,因为我想使用子类'父类中的类变量值。实际上,我找到了一种方法,但我觉得我可以做得更好。这是我目前的代码:

class Parent
  def self.test_settings
    const_set "PATH", "/tmp/#{self.name}"
  end
end

class Sub1 < Parent
  def self.name
    "one"
  end
  test_settings if Rails.env.test?
end

class Sub2 < Parent
  def self.name
    "two"
  end
  test_settings if Rails.env.test?
end

我的原始版本 - 无效,是:

class Parent
  def self.test_settings
    const_set "PATH", "/tmp/#{@@name}"
  end
  test_settings if Rails.env.test?
end

class Sub1 < Parent
  @@name = "sub1"
end

class Sub2 < Parent
  @@name = "sub2"
end

我将解释:我使用了一个类方法而不是一个变量(@@ name),我在尝试失败之前尝试过该方法。另外,我必须将函数调用test_settings if Rails.env.test?移动到子类,因为如果我将此代码放在那里,它会将self视为父类。

我很感激任何建议如何改进它以及为什么我的原创想法(使用@@ name并在父类中调用test_settings方法)不起作用。

2 个答案:

答案 0 :(得分:1)

这避免了使用类变量,但恕我直言更清晰,并避免了here提到的潜在问题

class Parent
  def self.test_settings(name)
    const_set "PATH", "/tmp/#{name}"
  end
end

class Sub1 < Parent
  test_settings("sub1") if Rails.env.test?
end

class Sub2 < Parent
  test_settings("sub2") if Rails.env.test?
end



irb(main):042:0> Sub1::PATH
=> "/tmp/sub1"
irb(main):043:0> Sub2::PATH
=> "/tmp/sub2"

答案 1 :(得分:0)

为了使其有效,您应该在@@name类中定义Parent

class Parent
  @@name = nil

  def self.test_settings
    const_set "PATH", "/tmp/#{@@name}"
  end
end

class Sub1 < Parent
  @@name = 'sub1'
  test_settings
end

class Sub2 < Parent
  @@name = 'sub2'
  test_settings
end

puts Sub1::PATH #=> /tmp/sub1
puts Sub2::PATH #=> /tmp/sub2

否则Ruby会告诉您@@name未初始化。