【问题标题】:Ruby Superclass creates a Stack errorRuby 超类创建 Stack 错误
【发布时间】:2014-11-25 19:46:42
【问题描述】:

下面的节目是试图接纳一位美国总统、法国总统的年龄和姓名。问题是法国总统在说出他的名字、年龄和公民身份后会说“bein sur”(不是我的想法)。我对这位法国总统的标语有意见。这是我的代码

class President
  attr_accessor :name, :age

  def initialize(name, age)
    @name = name 
    @age = age
  end 

end

class FrancePresident < President
  def self.citizenship
    "La France"
  end 

  def initialize(name, age)
    super(name, age)
  end

 def catchphrase
    "bien sur"
  end

   def name
    "#{name}, #{catchphrase}"
   end 

   def age
    "#{age}, #{catchphrase}"
   end 

   def citizenship
     "#{self.class.citizenship}, #{catchphrase}"
   end
end

class UnitedStatesPresident < President
  def self.citizenship
    "The Unites States of America"
  end
end

我认为我错误地引用了超类,因为我收到了下面的堆栈错误。

SystemStackError
stack level too deep
exercise.rb:29

我是 Ruby 新手,因此任何见解都会有所帮助。

【问题讨论】:

  • 从面向对象设计的角度来看,这有点混乱,因为您在这里所做的是将大量显示逻辑推入您的类中,您应该考虑model-view-presenter 在哪里这是模型,另一个类使用正确的措辞处理组合文本。
  • 这篇 MVP 文章似乎超出了我目前的技能水平,因为我只知道 Ruby 和一点 SML。希望我能在不久的将来再次访问这里,并拥有更多的专业知识。
  • @tadman:我现在开始在我的全栈课程中关注 MVP。您知道我可以查看的任何好资源吗?
  • 从学术角度来看,Design Patterns 这本书是一个很好的起点。对于更实用、更实用的方法,OS X/iOS API 严格应用这些原则。有很多像 Cocoa Design Patterns 这样的书解释了这些是如何工作的。

标签: ruby stack-overflow superclass


【解决方案1】:

您的name 函数会产生无限递归,因为它会调用自己:

def name
    "#{name}, #{catchphrase}" # <-- here, name calls this very function again and again
end

age 也是如此。他们应该分别调用实例变量@name@age

def name
    "#{@name}, #{catchphrase}"
end 

def age
    "#{@age}, #{catchphrase}"
end 

编辑

使用super 代替实例变量可能会更好,因为它清楚地表明您正在使用基类中的功能并向其添加一些东西(感谢您的提示,tadman!):

def name
    "#{super}, #{catchphrase}"
end 

def age
    "#{super}, #{catchphrase}"
end 

【讨论】:

  • 谢谢,那我还需要在FrancePresident 类中初始化吗?
  • 除了 w0lf 的修复,因为你有一个 name 方法,你不应该有 attr_accessor :name
  • @ClydeBrown 不,您可以将initialize 方法排除在类之外,因为它不会对超类中已经存在的功能添加任何内容。
  • 您可能希望将它们重写为"#{super}, #{catchphrase}"
  • @ClydeBrown 你会想听从 w0lf 的建议。他有正确的方法。
【解决方案2】:

这是基于所有 cmets 的结果。感谢您的所有帮助!

class President
  attr_accessor :name, :age

  def initialize(name, age)
    @name = name 
    @age = age
  end 

end

class FrancePresident < President
  def self.citizenship
    "La France"
  end 

 def catchphrase
    "bien sur"
 end

   def name
    "#{@name}, #{catchphrase}"
   end 

   def age
    "#{@age}, #{catchphrase}"
   end 

   def citizenship
     "#{self.class.citizenship}, #{catchphrase}"
   end
end

class UnitedStatesPresident < President
  def self.citizenship
    "The Unites States of America"
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-16
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-25
    • 2015-06-02
    相关资源
    最近更新 更多