Bawn
Bawn

Reputation: 509

Ruby Variables not working

I am having trouble incrementing a variable. This seems very trivial and easy but for some reason I can't get it to work.

I have a program moving a robot about a grid and it's fully working. I would now just like to count how many moves he makes.

Here is my code:

Class Robot

 @counter = 0
 def move
  @counter +=1
 end

 def print
  puts "Hurray the Markov chain has worked in #{@counter}"
 end

I get an error saying undefined method '+' operator. I have also tried

@counter = @counter + 1

What am I doing wrong?

Upvotes: 0

Views: 1235

Answers (3)

Todd A. Jacobs
Todd A. Jacobs

Reputation: 84443

TL;DR

Classes are executable code. Setting instance variables must generally be done within an instance method. Initialization is invoked by the #new method, which is created when you define "initialize" within your class.

Initializing Instance Variables for Robot#new

For example:

class Robot
  def initialize
    @counter = 0
  end

  def move
    @counter += 1
  end

  def print
    puts "Hurray the Markov chain has worked in #{@counter}"
  end
end

robot = Robot.new
robot.move
robot.print

will print what you expect:

Hurray the Markov chain has worked in 1

Coding Robot Without an Explicit Initializer

Coding is often a matter of style, and how you code something depends not only on what you're trying to do, but also on what you're trying to communicate. In this case, you could rewrite your class without an explicit initializer by ensuring that @counter is set to zero before you attempt to increment it. For example:

def move
  @counter.to_i.succ
end

This will ensure that if @counter is nil, it will be converted to an integer (in this case, zero) and then incremented. This might seem a bit "magical" to some folks, so you might also see people being more explicit with nil guards:

def move
  @counter ||= 0
  @counter  += 1
end

If @counter is nil or false, it is assigned the value of zero. This ensures that you'll be able to invoke numeric methods on its value.

Upvotes: 2

jstim
jstim

Reputation: 2432

your @counter variable is nil because it is not getting set on line 3.

As tomsoft pointed out, the variable is actually defined, but it is defined on the class, and not an instance of the class (an individual Robot).

To define the variable on an instance of the class, you need to initialize the @counter variable in an initializer method.

class Robot
  def initialize
    @counter = 0
  end

  def move
    @counter +=1
  end

  def print
    puts "Hurray the Markov chain has worked in #{@counter}"
  end
end

Upvotes: 3

tomsoft
tomsoft

Reputation: 4577

The way you define it is that @counter become a class variable, and not an instance variable.

class Robot
   @counter=0  # you are in class definition, not instance
   def self.print_counter
      puts @counter
   end
end
Robot.print_counter

returns

0

The only option is to define it in the initializer method

class Robot
  def initialize
     @counter=0
 end
end

Upvotes: 0

Related Questions