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

Ruby 3.1.2中使用&method(:host_name)处理URI数组莫名报错

URI提取基础域名时第三个元素报错的原因分析

环境信息

  • Ruby版本:3.1.2
  • 系统:Kubuntu 22.04

问题重现

用于从URI中提取基础域名(不含子域名)的方法:

def host_name(a)
  URI(a).host.sub(/\Awww\./, '')
end

使用示例:

uri_array = ['https://www.example.org', 'http://www.example.net/posts?a=1', 'www.example.com']
uri_array.map!(&method(:host_name))

预期输出:

['example.org', 'example.net', 'example.com']

实际触发报错:

(irb):14:in `host_name': undefined method `sub' for nil:NilClass (NoMethodError)

数组最终修改结果:

[
    [0] "example.org",
    [1] "example.net",
    [2] "www.example.com"
]

### 提问
为何处理数组第三个元素时失败?

## 原因解析
第三个元素`www.example.com`未携带协议头(http/https),Ruby的`URI`类解析这类字符串时,会将其整体识别为**路径(path)**而非主机名(host),导致`URI(a).host`返回`nil`,后续调用`sub`方法时触发`NoMethodError`。

直接在irb中验证:
```ruby
URI('www.example.com').host # => nil
URI('www.example.com').path # => "www.example.com"

前两个元素因带有协议头,URI能正确解析出host字段,所以可以正常执行sub操作。

修复方案

给未携带协议头的字符串自动补充默认协议(如http://)后再解析:

def host_name(a)
  uri_str = a.start_with?('http://', 'https://') ? a : "http://#{a}"
  URI(uri_str).host.sub(/\Awww\./, '')
end

测试修复后的方法:

uri_array = ['https://www.example.org', 'http://www.example.net/posts?a=1', 'www.example.com']
uri_array.map!(&method(:host_name))
# 输出:["example.org", "example.net", "example.com"]

这样即可正确处理所有三种格式的字符串。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 05:20:20