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

Ruby中YAML数据站点匹配条件失效问题求助

问题分析与解决方案

你的代码核心问题出在数据类型不匹配上,这是Ruby中符号(Symbol)与字符串(String)最容易踩的典型坑!

问题根源

当你用YAML.load_file加载yml文件时,文件里带冒号前缀的:washington、:briston这类内容,会被自动解析成Ruby的**Symbol类型**(比如:washington)。但你调用calc方法时传入的是带引号的字符串(比如':washington'),测试循环里用的也是纯字符串'washington'——符号和字符串在Ruby里是完全独立的对象,所以h['begin'] == start永远返回false,导致tmp一直为nil,直接触发break unless tmp`,自然没有任何输出结果。

具体修复方案

方案1:调用方法时传入符号(推荐)

直接把调用参数改成Symbol类型,去掉引号即可:

a = Train.new("my_path_to.yml")
a.calc(begin: :washington, end: :tokyo)

方案2:让方法兼容字符串输入

如果希望支持字符串形式的参数,在calc方法里把输入转换为Symbol:

class Train
  require 'yaml'
  def initialize(time)
    @time = YAML.load_file(time)
  end
  def calc(begin:, end:)
    ary = @time['time']
    start = begin.to_sym  # 统一转换为符号
    stop = end.to_sym
    res = []
    loop do
      tmp = ary.find { |h| h['begin'] == start }
      break unless tmp
      res << tmp
      start = tmp['end']
      break if start == stop
    end
    res  # 明确返回结果,Ruby方法默认返回最后一行,加上更清晰
  end
end

修复测试循环

你之前的for循环测试也犯了同样的类型错误,改成符号对比就能匹配成功:

ary = @time['time']
for i in ary
  if i['begin'] == :washington  # 用符号和YAML解析后的内容对比
    puts "good"
  else
    puts "no way"
  end
end

额外优化建议

你的loop写法虽然不会无限循环(找不到下一站时tmp为nil会触发break),但可以改成更Ruby化的写法:

def calc(begin:, end:)
  start = begin.to_sym
  stop = end.to_sym
  current = start
  path = []
  until current == stop
    segment = @time['time'].find { |h| h['begin'] == current }
    break unless segment
    path << segment
    current = segment['end']
  end
  path
end

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:20:32