gpt4 book ai didi

ruby - 你能传递一个返回错误的代码块给一个方法吗?

转载 作者:行者123 更新时间:2023-12-03 08:26:15 25 4
gpt4 key购买 nike

我经常发现自己处理这些情况:

require 'nokogiri'
require "open-uri"

url = "https://www.random_website.com/contains_info_I_want_to_parse"
nokodoc = Nokogiri::HTML(open(url))
# Let's say one of the following line breaks the ruby script
# because the element I'm searching doesn't contain an attribute.
a = nokodoc.search('#element-1').attribute('href').text
b = nokodoc.search('#element-2').attribute('href').text.gsub("a", "A")
c = nokodoc.search('#element-3 h1').attribute('style').text.strip

发生的情况是,我将创建大约 30 个变量,它们都在一个页面中搜索不同的元素,并且我将在多个页面上循环该代码。但是,其中一些页面的布局可能略有不同,并且不会有其中一个 div。这将破坏我的代码(例如,因为您不能在 nil 上调用 .attribute 或 .gsub )。但我永远无法事先猜到哪一行。
我的首选解决方案通常是在每一行周围加上:
begin
line #n
rescue
puts "line #n caused an error"
end

我希望能够做类似的事情:
url = "https://www.random_website.com/contains_info_I_want_to_parse"
nokodoc = Nokogiri::HTML(open(url))

catch_error(a, nokodoc.search('#element-1').attribute('href').text)
catch_error(b, nokodoc.search('#element-2').attribute('href').text.gsub("a", "A"))
catch_error(c, nokodoc.search('#element-3 h1').attribute('style').text.strip)

def catch_error(variable_name, code)
begin
variable_name = code
rescue
puts "Code in #{variable_name} caused an error"
end
variable_name
end

我知道将 & 放在每个新方法之前:
nokodoc.search('#element-1')&.attribute('href')&.text

但我希望能够在我的终端中显示带有“puts”的错误,以查看我的代码何时出现错误。

是否可以?

最佳答案

你不能通过你的code作为方法的常规参数,因为它会在传递给您的 catch_error 之前被评估(并引发异常)方法。你可以将它作为一个 block 传递——类似于

a = catch_error('element_1 href text') do 
nokodoc.search('#element-1').attribute('href').text
end

def catch_error(error_description)
yield
rescue
puts "#{error_description} caused an error"
end

注意不能通过 a方法为 variable_name : 在调用该方法之前没有在任何地方定义它,所以你会得到一个 undefined local variable or method错误。即使您定义 a早些时候,它将无法正常工作。如果您的代码在没有引发异常的情况下工作,则该方法将返回正确的值,但该值不会存储在方法范围之外的任何地方。如果有异常, variable_name将具有任何值 a在方法之前有( nil 如果你在没有设置的情况下定义它),所以你的错误消息会输出类似 Code in caused an error .这就是为什么我添加了 error_description范围。

如果您不想每次都指定错误描述,也可以尝试记录消息和回溯。
a = catch_error(nokodoc) do |doc|
doc.search('#element-1').attribute('href').text
end

def catch_error(doc)
yield doc
rescue => ex
puts doc.title # Or something else that identifies the document
puts ex.message
puts ex.backtrace.join("\n")
end

我在这里做了一项额外的更改:将文档作为参数传入,以便 rescue可以轻松地记录识别文档的内容,以防万一。

关于ruby - 你能传递一个返回错误的代码块给一个方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40598548/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com