Lets start with the biggest misnomer - in Ruby there is no separate step of declaring variables - Variables are declared as you set them.
What the difference? Look at Java for example:
public class Bicycle {
private int cadence;
private int gear;
private int speed;
public Bicycle(int startCadence, int startSpeed, int startGear) {
gear = startGear;
cadence = startCadence;
speed = startSpeed;
}
}
We have to declare all the instance variables before we set them in the initializer (Bicycle). The same code in Ruby reads:
class Bicycle
def initialize(cadence, speed, gear)
@cadence = cadence
@speed = speed
@gear = gear
end
end
There is no declaration - only assignment. Ruby will even let you access instance variables which have not been set without error.
irb(main):003:0> @not_set
=> nil
You can't do that (generally) in languages where variables must be defined*.
I have been taught to declare my instance variables with def
initialize. I have been under the impression that I could declare
instance variables only within my initialize methods.
Nonsense. You can assign instance variables anywhere. Its commonly done in everything from setters and mutators (methods that alter an object) to factory methods (class methods that return an instance) or anywhere that you are altering the state of an object.
class Book
def initialize(title, author)
@title = title
self.author = author # calls the setter.
end
# A factory method
def create_from_csv(filename)
# ...
end
# A very contrived setter
def author=(author)
@author = "#{author.forename.upcase}. #{author.surname}"
end
# a mutator
def out_of_print!
@out_of_print = true
@last_printed = Date.today
end
end
However the initialize method is where you should handle initializing your objects (duuh) and is thus the obvious place to set initial values.
attr_accessor. Thanks!initialize, then you could never, ever change them, except by callinginitializeagain. Who told you that? Also,initializeis just a method like any other method, so if you weren't allowed to assign to instance variables in methods, then you couldn't assign them ininitializeeither. The fact that you can assign them ininitializealready proves that you can assign them in methods, becauseinitializeis a method. This entire statement makes no sense.