如何利用嵌套数组数据创建Ruby Supplies类的实例?
修正Ruby商品实例创建代码的方案
我来帮你搞定这段代码的问题,你的需求是把爬虫返回的嵌套数组转换成一个个独立的Catalog::Supplies实例,同时用类变量保存所有实例对吧?先说说原代码里的几个核心问题:
原代码的问题点
- 索引越界风险:原while循环的条件
count <= name_url_price[0].length会让count走到数组长度的位置,而数组索引是从0到length-1的,这时候访问name_url_price[0][count]会拿到nil,甚至触发报错。 - 实例重复赋值:你在
initialize里反复修改同一个实例的属性,然后多次把它加到@@all里——最后@@all里的元素其实都是同一个对象,属性只会保留最后一个商品的值,完全达不到每个商品对应一个实例的目的。
修正后的实现方案
我推荐把单个实例的初始化和批量创建逻辑分开,这样代码更清晰,也符合面向对象的设计原则:
# 模拟爬虫返回的嵌套数组(三个子数组长度一致) name_url_price = [ ["无线鼠标", "机械键盘", "电竞耳机"], ["https://shop.com/mouse", "https://shop.com/keyboard", "https://shop.com/headset"], [89.9, 299.9, 399.9] ] module Catalog class Supplies attr_accessor :name, :price, :url @@all = [] # 初始化单个商品实例,接收独立的name、url、price def initialize(name, url, price) @name = name @url = url @price = price @@all << self # 创建实例时自动加入类变量 end # 类方法:批量从嵌套数组创建所有商品实例 def self.create_from_array(data) # 先校验所有子数组长度是否一致,避免数据残缺 unless data.all? { |arr| arr.length == data[0].length } raise ArgumentError, "所有子数组的元素数量必须相同哦" end # 遍历每个索引,取出对应位置的三个值创建实例 data[0].each_with_index do |name, index| url = data[1][index] price = data[2][index] new(name, url, price) end end # 对外提供获取所有实例的接口 def self.all @@all.clone # 返回副本,避免外部直接修改类变量数组 end end end # 调用批量创建方法 Catalog::Supplies.create_from_array(name_url_price) # 验证结果 Catalog::Supplies.all.each do |item| puts "商品:#{item.name} | 链接:#{item.url} | 价格:#{item.price}" end
方案优势
- 每个商品都是独立实例:再也不会出现同一个对象反复改属性的情况,
@@all里的每个元素都是不同的商品实例。 - 职责分离:
initialize只负责初始化单个实例,create_from_array专门处理批量创建逻辑,代码可读性更强。 - 数据校验:提前检查子数组长度是否一致,避免因为爬虫数据异常创建出不完整的商品实例。
- 封装类变量:用
self.all方法返回@@all的副本,防止外部代码直接修改类变量里的数组,保证数据安全。
内容的提问来源于stack exchange,提问作者qonepQQ
相关产品推荐
相关产品推荐

