John
John

Reputation: 443

Undefined method error when calling instance method on instance of same class

I have a csv file:

Name,Grade
John Smith,75
Sally Field,85

etc…….

That I am reading using the following class in a separate file 'test_scores.rb':

require'csv'
require_relative('./test_scores_student_class')

class TestScores
  attr_accessor :filename

  def initialize(filename)
    @filename = filename
  end

  def make_score_list
    score_list = []
    CSV.foreach(@filename, headers:true) do |record|
      name = record['Name']
      grade = record['Grade'].to_i

      student = Student.new(name, grade)
      score_list << student
    end

    score_list
  end

  def grade_count
    a = []
    b = []
    c = []
    d = []
    self.each do |student|
      binding.pry
      if student['Grade'] >= 90
        a << student
      elsif student['Grade'] >= 80 && student['Grade'] < 90
        b << student
      elsif student['Grade'] >= 70 && student['Grade'] < 80
        c << student
      else
        d << student
      end
    end
    puts ">= 90: #{a.count}"
    puts ">= 80: #{b.count}"
    puts ">= 70: #{c.count}"
    puts " < 70: #{d.count}"
  end

end

test_scores = TestScores.new('scores.csv')
grade_list = test_scores.make_score_list
grade_list.grade_count

When I attempt to call the method grade_count on the grade_list array I get the undefined method error. How can I re-write the method so that it is callable on grade_list while still preserving the functionality it is designed for?

Upvotes: 0

Views: 599

Answers (2)

Tony Hopkinson
Tony Hopkinson

Reputation: 20320

Well guessing your intent. score_list in the make_score_list method should be an instance variable

Then grade count should do @score_list.each.

Another way would be to make them both both class methods one returning an array of Student the other taking that as an argument.

The problem with your code is grade_count is a method on TestScores, not score_list.

Which would be another option, i.e creating a class that held an array of student.

Upvotes: 1

FlyingFoX
FlyingFoX

Reputation: 3509

Your grade_list is an Array and not an instance of your TestScores class. Therefore grade_list does not have a method called grade_count.

To fix that you can either make grade_count a class function and call it with an array parameter like TestScores.grade_count(grade_list) or you can make your TestScores class an Enumerable and make make_score_list return itself instead of an array.

Upvotes: 1

Related Questions