2

I am trying to learn Ruby and I am trying to call one instance method from another. My code is as follows:

class ScanTextInFile

  attr_accessor :content , :line_number

  def content
    @content
  end

  def line_number
    @line_number
  end

  def content= (text)
    @content = text
  end

  def line_number= (line)
    @line_number = line
  end

  def initialize (content , line_number)
    self.content = content
    self.line_number = line_number
    #self.calculate_word_frequency
  end

  def calculate_word_frequency
    words = self.content.split
    words_hash = Hash.new
    words.each do | word |
      word.downcase!
      if words_hash.has_key?
        words_hash[key] += 1
      else 
        words_hash[key] = 1 
      end
      highest_wf_count = words_hash.values.max
      words_hash.each { |key, value| highest_wf_words.push(key) }
    end 
  end
end

I am trying to calculate the number of times a word appears in a given string. I am using the instance method calculate_word_frequency for that. When I comment out the call to calculate_word_frequency the code runs fine

$ irb -I
irb(main):001:0> require_relative 'test'
=> true
irb(main):002:0> 
irb(main):003:0* 
irb(main):004:0* a = ScanTextInFile.new("Bla bla foo foo bar baz foo bar bar", 1)
=> #<ScanTextInFile:0x007fc7a39b01c8 @content="Bla bla foo foo bar baz foo bar bar", @line_number=1>

However, when I call the instance method calculate_word_frequency in the initialize block, I get an error saying ArgumentError: wrong number of arguments (0 for 1)

$ irb -I
irb(main):001:0> require_relative 'test'
=> true
irb(main):002:0> a = ScanTextInFile.new("Bla bla foo foo bar baz foo bar bar", 1)
ArgumentError: wrong number of arguments (0 for 1)

I tried removing the self while calling the method but I still get error. I don't know what's going wrong when I make the call to the method. What is the correct way to do this?

3 Answers 3

2

The error is pretty descriptive here, on line 32 you have this:

  if words_hash.has_key?

The method Hash#has_key? requires you pass in one argument, as in some_hash.has_key?("a_key")

I think you mean to use it like this: words_hash.has_key?(word).

Sign up to request clarification or add additional context in comments.

Comments

2

Change this:

  if words_hash.has_key?
    words_hash[word] += 1
  else 
    words_hash[word] = 1 
  end

To:

  if words_hash.has_key? word
    words_hash[word] += 1
  else 
    words_hash[word] = 1 
  end

You are using Hash#has_key method without providing the key argument to it, that's why it's failing.

2 Comments

he doesn't have a variable called key so this will fail again but ya, that's the gist.
You're right. I think, he meant to use word as the key for his hash. I updated my answer. Thanks!
1

If you're using attr_accessor, you don't need to define getters and setters for your instance variables. The whole point of using attr_accessor is that it does it for you. :) Also, getters and setters are generally only used by external classes and modules to access instances variables; within the class, just access the instance variables directly. Finally, you're not telling has_key? the key to look for, you're mixing up key and word, and you're referencing a data structure highest_wf_words that isn't defined anywhere.

Here's a revised version of your class. I don't understand exactly what you're trying to do—it looks like you're still writing the algorithm—but hopefully this is enough for you to move forward and continue working:

class ScanTextInFile
  attr_accessor :content, :line_number

  def initialize(content, line_number)
    @content = content
    @line_number = line_number
    calculate_word_frequency
  end

  def calculate_word_frequency
    words_hash = Hash.new(0) # Non-existent keys will default to a value of 0.
    highest_wf_words = Array.new

    @content.split.each do |word|
      words_hash[word.downcase] += 1
      highest_wf_count = words_hash.values.max # What is this for?
      highest_wf_words.concat(words_hash.keys) # What is this for?
    end

    p highest_wf_words
  end
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.