ruby 3.1:使用 &method(:name) 简化代码莫名失败

问题描述 投票:0回答:1

红宝石3.1.2 库班图 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"
]

为什么它应该在数组的第三个元素上失败。

ruby
1个回答
0
投票

这里的问题不是使用

&method
,而是将uri传递给
URI
。当要解析的uri不包含scheme(如http、https等)时,
URI
将无法提取主机属性:

irb(main):001> require 'uri'
=> true
irb(main):002> uri = URI('www.example.com')
=> #<URI::Generic www.example.com>
irb(main):003> uri.host
=> nil
irb(main):004> uri.path
=> "www.example.com"
irb(main):005> uri.host.sub(/\Awww\./, '')
(irb):5:in `<main>': undefined method `sub' for nil (NoMethodError)

uri.host.sub(/\Awww\./, '')
        ^^^^
        from <internal:kernel>:187:in `loop'
        from /Users/jason/.gem/ruby/3.3.0/gems/irb-1.12.0/exe/irb:9:in `<top (required)>'
        from /Users/jason/.gem/ruby/3.3.0/bin/irb:25:in `load'
        from /Users/jason/.gem/ruby/3.3.0/bin/irb:25:in `<main>'
irb(main):006>

但是,您可以在这种情况下使用

Addressable::URI.heuristic_parse

将输入转换为 URI。输入不必是有效的 URI — 该方法将使用启发式方法来猜测 URI 的用途。这不符合标准,只是用户友好。

irb(main):001> require 'addressable'
=> true
irb(main):002> uri = Addressable::URI.heuristic_parse('www.example.com')
=> #<Addressable::URI:0x2ee0 URI:http://www.example.com>
irb(main):003> uri.host
=> "www.example.com"
irb(main):004>
© www.soinside.com 2019 - 2024. All rights reserved.