Alex
Alex

Reputation: 109

I'm running into an error of 'split' for nil:NilClass in ruby even though it was just working

I was working on some code that I'm having a pretty tough time figuring out and then out of no where this error showed up saying:

in `process_data': undefined method `split' for nil:NilClass (NoMethodError)

So I undid the changes I made and it popped up again and again and I don't have the slightest clue as to what is causing it?
Code

class HiScore
    attr_reader :hiscore

    def initialize
        @hiscore = if File.exist?('hiscore.txt')
            read_file
        else
            build_new
        end
    end

    def show
        puts "Top 5 Scores"
        @hiscore.each do |r|
          puts r.each { |p| p }.join(" ")
        end
    end

    def build_new
        Array.new(5) {[1000, '--']}
        write_file()
    end

    def read_file()
        puts "read_file"
        #File.open('hiscore.txt', 'r') #{|f| f.each_line.map{|l| l.chomp!.split(',')}}\
        @hiscore = File.read("hiscore.txt").chomp!
        process_data(@hiscore)
    end

    def process_data(instance)
        @hiscore = @hiscore.split(",").to_a
        @hiscore = @hiscore.each_slice(2).to_a
    end

    def check(score)
        @hiscore.sort!{|s1, s2| s1[0] <=> s2[0]}
        max = @hiscore[4][0].to_i
        if score > max
            puts "Sorry no top score for you."
        else
            add_name(@score.to_s)
            # @hiscore.each do |row|
              # p row[0] do |column|
                  # puts column[0].to_i  
              # end
            # end
        end
    end

    def add_name(score)
        puts "You made it into the Top 5!"
        print "Enter your name: "
        @name = gets.chomp!.to_s
        @hiscore.push([score, @name]).sort!{|s1, s2| s1[0] <=> s2[0]}.pop
        #@hiscore = @scoreList
        #@hiscore = @scoreList
        write_file()

    end

    def write_file()
        File.open('hiscore.txt', 'w') do |f|
        @hiscore.each {|array| f.puts array.join(',')}
            #print "#{@hiscore}"
        end
    end

end

def start
    play = true
    while play == true
        num_guesses = 0
        answer = rand(1..1000)
        puts answer

        @game.show

        loop do
            print "Type in your guess: "
            guess = gets.chomp.to_i

            num_guesses += 1 
            unless guess == answer 
                message = if guess > answer 
                    "Too high"
                else
                    "Too low"
                end
                puts message 
            else
                puts "You got it!"
                puts "It took you #{num_guesses} guesses."
                @score = num_guesses
                @game.check(@score)

                break
            end
        end
        print "Would you like to play again? (y/n): "
        again = gets.chomp!
        if again == 'n'
            play = false
            puts "Ok, Bye!"
            exit
        elsif again == 'y'
            play = true
        end
    end
end

puts "I'm thinking of a random number from 1 to 1000"
puts "Can you guess it?"
@game = HiScore.new()
start()

Can anyone help with this?

Upvotes: 0

Views: 74

Answers (2)

swarn
swarn

Reputation: 1

It may also throw error, if "hiscore.txt" has values already comma separated and you are attempting to split it again with "," delimiter.

"@hiscore" is instance variable to the function read_file, so scope will be limited to that function itself. In "process_data(instance)" function if you use instance inplace of "@hiscore" and that variable has right data then it will process correctly.

Upvotes: 0

Matouš Bor&#225;k
Matouš Bor&#225;k

Reputation: 15954

The direct cause for the error is that the @hiscore variable is nil in the process_data method when trying to be split-ed.

I guess that the underlying error might be the following line in the read_file method:

@hiscore = File.read("hiscore.txt").chomp!

According to the documentation, the chomp! method returns nil when it makes no modifications to the string, i.e. when it does not strip off any newline characters from the end of the string. You probably want to use chomp instead which simply returns the original string if it has no newline at the end.

Upvotes: 1

Related Questions