Ruby Error: nil can't be coerced to Integer
Ruby Error: nil can't be coerced to Integer
我只是在玩一些纯粹的 Ruby 以获得更好的理解并试图找到一个数的素数,而不仅仅是使用我知道的素数 gem,但是我写这些都是为了理解,而不是为了解决问题本身。
我写了下面的代码:
class LargestPrimeFactor
# goal: find largest prime factor of 10 to start
attr_accessor :factors_list, :prime_factors, :idx, :below_n, :half_num
def initialize(below_n)
@below_n = below_n
@half_num = (below_n/2).floor
@idx = 2
@factors_list = []
@prime_factors = []
end
def prime_checker
sorted_list = factors_list.sort
sorted_list_length = sorted_list.length
puts "Sorted list of factors so far: #{sorted_list}"
sorted_list.combination(2) do |el, others|
if !prime_factors.include?(el) && others % el == 0
prime_factors << el
end
end
puts "Prime checker returned: #{prime_factors}"
end
def factors
congruent = (below_n % idx == 0)
not_listed = !factors_list.include?(idx)
number_candidate = idx
factors_list_length = factors_list.length
if congruent && not_listed && number_candidate
factors_list << number_candidate
puts "#{idx}"
puts "#{below_n}"
puts "why nil? #{below_n.divmod(idx)[0]}"
tmp = below_n.divmod(idx)[0]
idx = tmp #return number of times it divides in
puts "idx now: #{idx}"
elsif factors_list_length > 0 && factors_list[-1] - idx < 0
primes = prime_checker
puts "Prime factors: #{primes}"
puts "COMPLETE"
else
idx += 1
end
end
def find_primes
(1..half_num).each do |el|
factors
end
end
end
p = LargestPrimeFactor.new(below_n=10)
p.find_primes
但是,当我 运行 ruby largest_prime_factor.rb
我得到以下输出错误:
2
10
why nil? 5
idx now: 5
Traceback (most recent call last):
5: from largest_prime_factor.rb:65:in `<main>'
4: from largest_prime_factor.rb:56:in `find_primes'
3: from largest_prime_factor.rb:56:in `each'
2: from largest_prime_factor.rb:57:in `block in find_primes'
1: from largest_prime_factor.rb:46:in `factors'
largest_prime_factor.rb:46:in `-': nil can't be coerced into Integer (TypeError)
我很困惑,因为我认为 idx
会在第 46 行设置为 5
,但我将其解释为 nil
不知何故.关于如何在此方法中访问和设置此变量,我遗漏了什么?
谢谢!
您已经声明了 reader 但不是 @idx
的编写器,因此虽然 idx
有效并且 returns 实例变量 @idx
,但您无法写入。
要么直接写入实例变量(@idx = 5
),要么做一个writer(attr_accessor :idx
)写入self.idx
(self.idx = 5
)。请注意,在后一种情况下,需要显式 self
,这样您就不会不小心创建一个具有相同名称的新局部变量。
您的 idx += 1
行也需要类似地更新,以及您尝试写入访问器的任何其他地方。
Silvio Mayolo 没有解释错误
更改实例变量的问题 -- 只是问题之一。但原因是另一个
例如这段代码:
class Foo
attr_accessor :bar
def initialize
@bar = 0
end
def baz
p x
10.times do
if bar < 6
@bar += 1
end
end
end
end
Foo.new.baz
会加薪
undefined local variable or method `x'
但是这段代码:
class Foo
attr_accessor :bar
def initialize
@bar = 0
end
def baz
10.times do
if bar < 6
x = 1
@bar += 1
else
p x
end
end
end
end
Foo.new.baz
将打印
nil
nil
nil
nil
所以您的代码中的 factors_list[-1] - idx < 0
会引发错误。局部变量idx
是被声明的,但是没有被初始化,因为那些if
分支没有被执行
我很惊讶为什么你的问题被否决了。读者没弄明白题的感觉,还有Silvio Mayolo
我只是在玩一些纯粹的 Ruby 以获得更好的理解并试图找到一个数的素数,而不仅仅是使用我知道的素数 gem,但是我写这些都是为了理解,而不是为了解决问题本身。
我写了下面的代码:
class LargestPrimeFactor
# goal: find largest prime factor of 10 to start
attr_accessor :factors_list, :prime_factors, :idx, :below_n, :half_num
def initialize(below_n)
@below_n = below_n
@half_num = (below_n/2).floor
@idx = 2
@factors_list = []
@prime_factors = []
end
def prime_checker
sorted_list = factors_list.sort
sorted_list_length = sorted_list.length
puts "Sorted list of factors so far: #{sorted_list}"
sorted_list.combination(2) do |el, others|
if !prime_factors.include?(el) && others % el == 0
prime_factors << el
end
end
puts "Prime checker returned: #{prime_factors}"
end
def factors
congruent = (below_n % idx == 0)
not_listed = !factors_list.include?(idx)
number_candidate = idx
factors_list_length = factors_list.length
if congruent && not_listed && number_candidate
factors_list << number_candidate
puts "#{idx}"
puts "#{below_n}"
puts "why nil? #{below_n.divmod(idx)[0]}"
tmp = below_n.divmod(idx)[0]
idx = tmp #return number of times it divides in
puts "idx now: #{idx}"
elsif factors_list_length > 0 && factors_list[-1] - idx < 0
primes = prime_checker
puts "Prime factors: #{primes}"
puts "COMPLETE"
else
idx += 1
end
end
def find_primes
(1..half_num).each do |el|
factors
end
end
end
p = LargestPrimeFactor.new(below_n=10)
p.find_primes
但是,当我 运行 ruby largest_prime_factor.rb
我得到以下输出错误:
2
10
why nil? 5
idx now: 5
Traceback (most recent call last):
5: from largest_prime_factor.rb:65:in `<main>'
4: from largest_prime_factor.rb:56:in `find_primes'
3: from largest_prime_factor.rb:56:in `each'
2: from largest_prime_factor.rb:57:in `block in find_primes'
1: from largest_prime_factor.rb:46:in `factors'
largest_prime_factor.rb:46:in `-': nil can't be coerced into Integer (TypeError)
我很困惑,因为我认为 idx
会在第 46 行设置为 5
,但我将其解释为 nil
不知何故.关于如何在此方法中访问和设置此变量,我遗漏了什么?
谢谢!
您已经声明了 reader 但不是 @idx
的编写器,因此虽然 idx
有效并且 returns 实例变量 @idx
,但您无法写入。
要么直接写入实例变量(@idx = 5
),要么做一个writer(attr_accessor :idx
)写入self.idx
(self.idx = 5
)。请注意,在后一种情况下,需要显式 self
,这样您就不会不小心创建一个具有相同名称的新局部变量。
您的 idx += 1
行也需要类似地更新,以及您尝试写入访问器的任何其他地方。
Silvio Mayolo 没有解释错误
更改实例变量的问题 -- 只是问题之一。但原因是另一个
例如这段代码:
class Foo
attr_accessor :bar
def initialize
@bar = 0
end
def baz
p x
10.times do
if bar < 6
@bar += 1
end
end
end
end
Foo.new.baz
会加薪
undefined local variable or method `x'
但是这段代码:
class Foo
attr_accessor :bar
def initialize
@bar = 0
end
def baz
10.times do
if bar < 6
x = 1
@bar += 1
else
p x
end
end
end
end
Foo.new.baz
将打印
nil
nil
nil
nil
所以您的代码中的 factors_list[-1] - idx < 0
会引发错误。局部变量idx
是被声明的,但是没有被初始化,因为那些if
分支没有被执行
我很惊讶为什么你的问题被否决了。读者没弄明白题的感觉,还有Silvio Mayolo