[英]NoMethodError: undefined method `+' for nil:NilClass for variable in private method
Hi I have a service class which is pulling information from Hubspot.嗨,我有一项服务 class 正在从 Hubspot 提取信息。
module HubspotApi
class CompanyImporter < ApplicationService
MAX_RETRIES = 3
def initialize(company_vid)
@company_vid = company_vid
@attempt = 0
end
def service_body
imported_profile
end
private
attr_reader :company_vid, :attempt
def imported_profile
## load hubspot record over here and take other actions
end
def hubspot_record
@hubspot_record ||= Hubspot::Company.find_by_id(company_vid.to_i)
rescue Hubspot::RequestError
if (attempt += 1) <= MAX_RETRIES
sleep 2**attempt
retry
else
@messages << 'Raise some hubspot error'
end
end
end
end
I tried calling this with an incorrect company_vid
to make sure the retry works properly and I keep getting the error:我尝试使用不正确的company_vid
调用它以确保重试正常工作,但我不断收到错误消息:
NoMethodError: undefined method `+' for nil:NilClass from `rescue in hubspot_record'
Caused by Hubspot::RequestError: Response body: {"status":"error","message":"resource not found"}
I am not sure if I am having a brain-fart here but I just cannot figure out the error here since the variable should be defined我不确定我是否在这里放屁,但我只是无法弄清楚这里的错误,因为应该定义变量
In Ruby, local variables are defined from the moment that an assignment to them is parsed (NOT executed).在 Ruby 中,局部变量从对它们的赋值被解析(不执行)的那一刻起定义。
Since you are assigning to attempt
, Ruby will make attempt
a local variable of hubspot_record
.由于您分配给attempt
,因此 Ruby 将attempt
使用hubspot_record
的局部变量。 However, since it is not initialized, it will evaluate to nil
.但是,由于它没有被初始化,它将评估为nil
。
attempt += 1
is equivalent to相当于
attempt = attempt + 1
And since attempt
is un-initialized and evaluates to nil
, this is essentially evaluating nil + 1
.并且由于attempt
未初始化并评估为nil
,这本质上是评估nil + 1
。
If you want to use the attribute reader method, you have to make it clear to Ruby that you are intending a message send and not access a local variable.如果要使用属性读取器方法,则必须向 Ruby 说明您打算发送消息而不是访问局部变量。 There are two ways to do this: a local variable cannot have a receiver and a local variable cannot have an argument list.有两种方法可以做到这一点:局部变量不能有接收者,局部变量不能有参数列表。 So, if you add either one of those, Ruby will know it is a message send and not a local variable:因此,如果您添加其中任何一个,Ruby 将知道它是消息发送而不是局部变量:
attempt()
self.attempt
Either one of those will make it clear to Ruby that you intend to call the HubspotApi::CompanyImporter#attempt
method.其中任何一个都会让 Ruby 清楚您打算调用HubspotApi::CompanyImporter#attempt
方法。
However, that still will not work, because you are trying to assign to and you don't actually have an attribute writer, so your next error message is going to be something like但是,这仍然行不通,因为您正在尝试分配给并且您实际上没有属性编写器,因此您的下一条错误消息将类似于
NoMethodError: undefined method `attempt=' for HubspotApi::CompanyImporter
The way to fix this problem pre-Ruby 2.7 is to:在 Ruby 2.7 之前解决这个问题的方法是:
change attr_reader:attempt
to attr_accessor:attempt
将attr_reader:attempt
更改为attr_accessor:attempt
And和
def hubspot_record
@hubspot_record ||= Hubspot::Company.find_by_id(company_vid.to_i)
rescue Hubspot::RequestError
if (self.attempt = attempt + 1) <= MAX_RETRIES ## This was fixed in Ruby 2.7 but for earlier versions you need to read using self and write directly.
sleep 2**attempt
retry
else
@messages << 'Raise some hubspot error'
end
end
Link for update in Ruby 2.7: https://blog.saeloun.com/2019/12/24/ruby-2-7-allows-calling-a-private-method-with-self.html Ruby 2.7 中的更新链接: https://blog.saeloun.com/2019/12/24/ruby-2-7-allows-calling-a-private-method-with-self.Z5E056FDC70D8226C
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.