52

Rubyでは、サブクラスから継承されたメソッドを呼び出すと、そのメソッドが古い定数ではなく新しい定数を使用するように、サブクラスの定数を「オーバーライド」する方法はありますか? 例えば:

class SuperClass
  CONST = "Hello, world!"
  def self.say_hello
    CONST
  end
end

class SubClass < SuperClass
  override_const :CONST, "Hello, Bob!"
end

SuperClass.say_hello # => "Hello, world!"
SubClass.say_hello   # => "Hello, Bob!"

そうでない場合、代わりにこのようなことを行う方法はおそらくありますか?

class SuperClass
  CONST = "Hello, world!"
  def self.say_hello
    CONST
  end
end

SubClass = SuperClass.clone
SubClass.send(:remove_const, :CONST)
SubClass.const_set(:CONST, "Hello, Bob!")

SubClass.say_hello # => "Hello, Bob!"

注: irb で 2 番目の例を試してみましたが、クラスのクローンを作成した後、クラス メソッドが CONST にアクセスできないように見えることを除いて、うまくいくようです。

irb(main):012:0> SubClass.say_hello
NameError: uninitialized constant Class::CONST
        from (irb):4:in `say_hello'
        from (irb):12
        from C:/Ruby193/bin/irb:12:in `<main>'
4

3 に答える 3

79

I've done this by simply redefining the constant in the subclass, and then referring to it in methods as self.class::CONST in instance methods and self::CONST in class methods. In your example:

class SuperClass
  CONST = "Hello, world!"
  def self.say_hello
    self::CONST
  end
end

class SubClass < SuperClass
  CONST = "Hello, Bob!"
end

SubClass.say_hello #=> "Hello, Bob!"
于 2012-11-05T14:50:00.160 に答える
8

親クラスで次のような定数を参照できます。

インスタンスメソッドの場合:self.class::CONST

自己メソッドの場合:self::CONST

class SuperClass
  CONST = "Hello, world!"
  def print_const
    puts self.class::CONST
  end

  def self.print_const
    puts self::CONST
  end

end

class SubClass < SuperClass
  CONST = "Hello, Bob!"
end

SubClass.new.print_const #=> "Hello, Bob!"
SubClass.print_const #=> "Hello, Bob!"
于 2018-06-18T17:36:24.010 に答える