Ruby开发:如何根据用户输入精准删除Weapon类的指定剑实例
问题根源与修正方案
触发异常的核心原因
SWORDS.delete_if的判断块没有接收当前遍历的数组元素作为块参数,判断逻辑完全和数组内的武器实例脱钩
块内写的@weapon_name == delete_target,在类方法的作用域下引用的是Weapon类自身的实例变量,不是每个武器实例的weapon_name属性。这个变量的取值是固定的,最终会停留在最后一次被赋值的状态——也就是最后创建的那把武器的名称,不会随着数组遍历逐个变化。
这直接对应你观察到的异常现象:当用户输入刚好等于这个固定值时,delete_if对数组里所有元素的判断结果都是true,会一次性删掉所有武器;当输入和这个固定值不匹配时,所有判断结果都是false,没有任何删除效果。- 匹配规则不对等
你对用户输入做了downcase.strip的格式清洗,但对比时没有对存储的武器名称做相同处理。比如武器名存储为"Epic Sword"时,用户输入全小写带多余空格的内容本来想匹配,最终也会匹配失败。 - 代码附带的其他问题
initialize方法里的self.ascii_image = ascii_image是无效代码:方法参数列表里没有传入ascii_image的值,执行时会触发未定义变量报错- 创建武器实例的
Weapon.new(...)写在类体中间位置,会在程序加载类的时候就自动执行,不符合交互逻辑里“用户操作时才创建武器”的设计
可用的修正代码
调整类方法self.delete的实现,即可实现精准匹配删除单把武器的效果:
def self.delete puts "Which weapon would you like to delete?" delete_target = gets.chomp.downcase.strip # 块参数sword代表数组中当前遍历到的每一个Weapon实例 SWORDS.delete_if do |sword| # 和用户输入用完全一致的格式清洗规则处理武器名,再做匹配 sword.weapon_name.downcase.strip == delete_target end puts SWORDS end
逻辑说明:修正后会逐个遍历
SWORDS中的每一把武器,取出对应实例的武器名称、做和用户输入相同的格式清洗后再做对比,仅删除名称匹配的条目,不会出现全量删除或匹配失效的问题。
内容的提问来源于stack exchange,提问作者zedd0
相关产品推荐
相关产品推荐

