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.idxself.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