拼音错误:不能将 nil 强制转换为整数



我只是在玩一些纯Ruby来获得更好的理解,并试图找到一个数字的素数,而不仅仅是使用素数宝石,我知道这一点,但我写这一切都是为了理解,而不是解决问题本身。

我写了以下代码:

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。关于如何在此方法中访问和设置此变量,我缺少什么?

谢谢!

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

您已经为@idx声明了读取器,但没有声明写入器,因此当idx工作并返回实例变量@idx时,您无法对其进行写入。

直接写入实例变量(@idx = 5(,或者创建写入程序(attr_accessor :idx(并写入self.idx(self.idx = 5(。请注意,在后一种情况下,需要显式self,这样就不会意外地生成一个同名的新局部变量。

您的idx += 1行也需要进行类似的更新,以及尝试写入访问器的任何其他位置。

最新更新