【问题标题】:Ruby: share a class variable between a parent class and its subclassesRuby:在父类及其子类之间共享一个类变量
【发布时间】:2015-05-11 18:45:09
【问题描述】:

我正在尝试做我在标题中描述的事情,因为我想在父类中使用子类的类变量值。实际上,我找到了一种方法,但我觉得我可以做一些更好的事情。这是我当前的代码:

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 方法)不起作用,我将不胜感激。

【问题讨论】:

  • 您的代码中是否有相同的拼写错误(Paernt 而不是 ParentRail 而不是 Rails)?
  • @@name 被称为类变量,它将为您提供最新的值,并且它是跨继承的共享变量。其他问题我没有感到抱歉。 :)
  • 请注意,实现self.name 覆盖/阴影Module#name

标签: ruby inheritance class-variables


【解决方案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"

【讨论】:

    【解决方案2】:

    为了让它工作,你应该在Parent类中定义@@name

    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 未初始化。

    【讨论】:

    • 小心这个 - 一旦这个 sn-p 运行,@@name 将在两个子类中都有值 'sub2'
    猜你喜欢
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-20
    • 2013-12-28
    • 1970-01-01
    相关资源
    最近更新 更多