Home > Blockchain >  Ruby Error: nil can't be coerced to Integer
Ruby Error: nil can't be coerced to Integer

Time:04-09

I'm just playing with some pure Ruby to gain better understanding and trying to find the primes of a number, without just using the Prime gem, which I'm aware of but I wrote this all for understanding, not to solve a problem per se.

I've written the following code:

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

But, when I run ruby largest_prime_factor.rb I get the following output error:

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)

I'm confused in that I thought the idx would be set to 5 at line 46 at that point, but I'm interpreting this as it being nil somehow. What am I missing about how this variable is being accessed and set within this method?

Thanks!

CodePudding user response:

Silvio Mayolo doesn't explain error

Problem with changing instance variable -- is just one of the problem. But reason is another

For example this code:

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

will raise

undefined local variable or method `x'

but this code:

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

will print

nil
nil
nil
nil

So factors_list[-1] - idx < 0 in your code raises error. Local variable idx is is declared, but not initialized, because those if branch is not executed

I am very surprised why your question is downvoted. The feeling that readers have not figured out the question, as well as Silvio Mayolo

CodePudding user response:

You've declared a reader but not a writer for @idx, so while idx works and returns the instance variable @idx, you can't write to it.

Either write to the instance variable directly (@idx = 5), or make a writer (attr_accessor :idx) and write to self.idx (self.idx = 5). Note that, in the latter case, an explicit self is required so that, again, you don't accidentally make a new local variable with the same name.

Your idx = 1 line will also need to be updated similarly, and any other place where you try to write to an accessor.

  •  Tags:  
  • ruby
  • Related