You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby中如何在Game类访问Player类赋值的name变量

核心错误说明

你代码跑不通的本质是搞混了Ruby的变量作用域规则,同时类之间的传值逻辑写得不对:

  • 你写的@@name是类变量,仅在存在继承关系的类层级中共享,你的Player和Game是两个完全独立、无继承关联的类,两边定义的@@name根本不是同一个变量,自然读不到赋值结果。
  • 你定义的attr_accessor :name是针对实例变量@name生成读写方法,和你代码里用的@@name没有任何关系,等于这段accessor代码完全没生效。
正确实现方案

方案1:显式传值(最推荐,符合面向对象设计原则)

不要依赖隐式的跨类共享变量,Player实例拿到用户输入的名字后,显式赋值给Game实例的name属性即可,逻辑清晰无隐式依赖,不会出奇怪的作用域bug:

class Game 
  attr_accessor :name

  def display_name
    puts "Name is #{@name}"
  end 
end 

class Player 
  attr_accessor :name

  def get_name
    puts "What is your name? "
    @name = gets.chomp # 把输入存在当前Player实例的实例变量里
  end  
end 

player = Player.new
player.get_name
game = Game.new
game.name = player.name # 显式把player存储的名字传递给game实例
game.display_name

方案2:全局变量共享(极度不推荐,仅作原理说明)

如果非要实现一处赋值、所有类都能直接读的效果,可以用Ruby全局变量(变量名以$开头),但这种写法会让代码依赖关系混乱,后续维护很容易出难排查的bug,非极端场景不要用:

class Game 
  def display_name
    puts "Name is #{$name}"
  end 
end 

class Player 
  def get_name
    puts "What is your name? "
    $name = gets.chomp
  end  
end 

player = Player.new
player.get_name
game = Game.new
game.display_name
补充规则说明
  • Ruby变量作用域区分规则:
    • 局部变量:小写/下划线开头,仅在当前代码块/方法内生效
    • 实例变量:@开头,属于单个类实例对象,不同实例之间互不干扰
    • 类变量:@@开头,仅在当前类的整个继承树内共享,无继承关系的类之间同名类变量完全独立
    • 全局变量:$开头,整个程序运行周期内全局生效
  • attr_accessor :属性名是语法糖,本质是自动生成对应实例变量的读、写两个方法,和类变量、全局变量无关,你之前的写法等于写了没用上的方法。

内容的提问来源于stack exchange,提问作者Oni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 04:01:07