Search code examples
arraysrubyeachinstance-variables

Ruby - Error accessing instance variables


I'm learning Ruby, and I'm having a problem while making a program.

I have a class "LineAnalyzer" that has 4 parameters (2 provided and 2 calculated). Both calculated params are: @high_wf_count (integer) and @high_wf_words (array). Then, I have this one:

class Solution < LineAnalyzer
    attr_reader :analyzers, 
                :highest_count_across_lines, 
                :highest_count_words_across_lines

    def initialize
        @analyzers = [] 
    end

    def analyze_file
        File.foreach('test.txt') do |line|
            @analyzers << LineAnalyzer.new(line.chomp,@analyzers.length+1)
        end 
    end

    def calculate_line_with_highest_frequency
        @highest_count_words_across_lines = []
        @highest_count_across_lines = @analyzers.max_by do 
            |a| a.instance_variable_get(:@highest_wf_count)
        end .instance_variable_get(:@highest_wf_count)

        @highest_count_words_across_lines << @analyzers.each do
            |a| a.instance_variable_get(:@highest_wf_count) == @highest_count_across_lines
        end .instance_variable_get(:@highest_wf_words)
    end    
end

The problem is that I cannot append the array @highest_wf_count to @highest_count_words_across_lines in the way I've done (it returns nil). But, I've previously taken the integer @highest_wf_count in the same way perfectly.

Can anyone tell me where's the problem?

Thanks in advance!


Solution

  • It seems that your problem is in this bit of code:

    @highest_count_words_across_lines << @analyzers.each do
        |a| a.instance_variable_get(:@highest_wf_count) == @highest_count_across_lines
    end .instance_variable_get(:@highest_wf_words)
    

    Preferably formatted as:

    @highest_count_words_across_lines << @analyzers.each do |analyzer|
      analyzer.instance_variable_get(:@highest_wf_count) == @highest_count_across_lines
    end.instance_variable_get(:@highest_wf_words)
    

    The problem here is that you are calling .instance_variable_get(:@highest_wf_words) on the result of the :each method.

    A few lines above, you are doing something similar, where you call .instance_variable_get(:@highest_wf_count) on the result of the :max_by method, and it is working.

    The difference between :max_by and :each is that :max_by returns a single analyzer, whereas :each returns the array of @analyzers over which it is iterating.

    When you call :instance_variable_get(:@highest_wf_words) on that array, it's returning nil because an array will not have an instance variable named :@highest_wf_words

    That is where your problem exists.

    Sidenote:

    It is generally not good practice to ever use :instance_variable_get. I would recommend adding to your analyzer class attr_reader :highest_wf_words, :highest_wf_count

    Then, instead of calling analyzer.instance_variable_get(:@highest_wf_words), you can just call analyzer.highest_wf_words