Ruby 基于类的名称声明实例变量值是一种不好的做法吗?

Ruby 基于类的名称声明实例变量值是一种不好的做法吗?,ruby,oop,Ruby,Oop,假设我有两个子类继承自基类,如下所示: class Base def initialize @name = self.class.name @num1 = 10; @num2 = 5; end def speak puts "My name is #{name}" end end class Sub1 < Base end class Sub2 < Base end class Sub3 < Base end 第一种

假设我有两个子类继承自基类,如下所示:

class Base

  def initialize
    @name = self.class.name
    @num1 = 10;
    @num2 = 5;
  end

  def speak
    puts "My name is #{name}"
  end

end

class Sub1 < Base
end

class Sub2 < Base
end

class Sub3 < Base
end

第一种方法更简洁。您可能应该做的是以懒散的方式对此进行评估:

def name
  @name ||= self.class.to_s.split(/::/).last
end

这样,您就不必担心赋值问题,任何子类都可以在必要时通过重写进行初始化。您的
speak
方法将继续工作,无需修改,因为您可能首先声明了
attr\u reader:name
,以使其工作。

我认为这是毫无意义的,请查看以下输出:

class Base
   def name
     self.class.name
   end
end

class Sub1 < Base
  # This declaration is useless
  def name
    self.class.name
  end
end

class Sub2 < Base
end

b = Base.new
b.name # "Base"

c = Sub1.new
c.name # "Sub1"

d = Sub2.new
d.name # "Sub2" (this function is inherited from base, but is called from Sub2 class context)

如果
@name
总是要与类名相等,则不需要它–只需直接使用
self.class.name
myObject.class.name
,或者定义一个访问器方法,如果不想从外部使用
.class.name
,则返回它。手动初始化它将是一种糟糕的做法,因为您必须始终记住在每个子类中进行初始化,并且对子类名称的更改需要复制到初始化中


如果
@name
并不总是等于每个子类中的类名,那么我个人仍然会提供一个默认实现,在该实现中,它是从
self.class.name
初始化的,并根据需要让子类覆盖它。

出于好奇,为什么还要将类名分配给ivar呢?已经知道了;我只需要定义一个
name
访问器,它返回
self.class.name
。当您可以从外部使用
self.class.name
myObject.class.name
时,为什么需要
@name=self.class.to
访问器呢?请注意,如果您将
Sub1
的倒数第二行替换为
@name=self.class.to
,那么
Sub1.new.instance_variable_get(:@name)#=>“Sub1”
。(您可以改为编写
…instance\u variable\u get('@name')
)。
class Base
   def name
     self.class.name
   end
end

class Sub1 < Base
  # This declaration is useless
  def name
    self.class.name
  end
end

class Sub2 < Base
end

b = Base.new
b.name # "Base"

c = Sub1.new
c.name # "Sub1"

d = Sub2.new
d.name # "Sub2" (this function is inherited from base, but is called from Sub2 class context)
 Sub2.superclass.name # "Base"