TheRookierLearner
TheRookierLearner

Reputation: 4173

How do I call one instance method in a class from another in Ruby?

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?

Upvotes: 2

Views: 189

Answers (3)

Anthony
Anthony

Reputation: 15997

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).

Upvotes: 2

mwp
mwp

Reputation: 8477

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

Upvotes: 1

K M Rakibul Islam
K M Rakibul Islam

Reputation: 34336

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.

Upvotes: 2

Related Questions