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

Ruby类中声明的实例变量无法被方法识别,方法内声明则正常

实例变量与类实例变量的那些坑——从Java转Ruby必看

嘿,刚从Java转Ruby确实会碰到不少变量作用域的小误区,我来帮你把这个问题掰扯清楚~

首先得明确一个Ruby和Java不一样的核心规则:

在Ruby的类体中直接定义的@name_array,不是实例对象的实例变量,而是类的实例变量!

换句话说,这个@name_array是属于Problem022这个类本身的,而你通过Problem022.new创建出来的实例对象,有自己独立的实例变量空间,和类的实例变量完全是两回事。你的do_problem、read_input这些实例方法,是属于实例对象的,它们访问的@变量是实例对象自己的,自然就找不到类里定义的那个@name_array啦。

对比Java的话,Java里类中直接定义的变量默认是实例变量,但Ruby的规则刚好在这一点上有差异,很容易混淆。

解决方案有两种,看你的需求选:

1. 定义真正的实例对象变量(最常用)

如果每个Problem022的实例都需要自己独立的name_array,那就在实例的初始化方法里定义它:

class Problem022
  FILENAME = "resources/p022_names.txt"

  # 初始化实例时创建实例变量
  def initialize
    @name_array = []
  end

  def do_problem
    read_input()
    sort_input()
    # 更多操作
  end

  def read_input
    File.open(FILENAME, "r") do |file|
      file.each_line do |line|
        scanner = StringScanner.new(line)
        while scanner.exist?(/,/) do
          # 这里可以直接操作@name_array了,它属于当前实例
        end
      end
    end
  end

  def sort_input
    @name_array.sort!
    # 后续排序逻辑
  end
end

2. 用类共享的变量(如果所有实例共用同一个数组)

如果这个数组是整个类共享的,不需要每个实例独立拥有,那可以把它改成类变量(用@@前缀),或者保留类实例变量并通过类方法访问:

方式A:类变量
class Problem022
  FILENAME = "resources/p022_names.txt"
  @@name_array = [] # 类变量,所有实例共享

  def do_problem
    read_input()
    sort_input()
  end

  def read_input
    File.open(FILENAME, "r") do |file|
      file.each_line do |line|
        scanner = StringScanner.new(line)
        while scanner.exist?(/,/) do
          @@name_array << "提取到的名字" # 直接操作类变量
        end
      end
    end
  end

  def sort_input
    @@name_array.sort!
  end
end
方式B:类实例变量+类方法(更Ruby风格的类共享变量写法)
class Problem022
  FILENAME = "resources/p022_names.txt"
  @name_array = [] # 类实例变量

  # 类方法,提供访问类实例变量的入口
  def self.name_array
    @name_array
  end

  def do_problem
    read_input()
    sort_input()
  end

  def read_input
    File.open(FILENAME, "r") do |file|
      file.each_line do |line|
        scanner = StringScanner.new(line)
        while scanner.exist?(/,/) do
          # 通过类方法访问类实例变量
          self.class.name_array << "提取到的名字"
        end
      end
    end
  end

  def sort_input
    self.class.name_array.sort!
  end
end

最后再划个重点

Ruby里:

  • 实例方法中的@xxx → 属于当前实例对象
  • 类体中的@xxx → 属于类本身(类实例变量)
  • 类体中的@@xxx → 类变量,所有实例共享

从Java转过来一定要把这个差异记牢,就不会再踩这种变量找不到的坑啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:27:11