Learn Object Oriented Programming

Don't use instance variables as global variables

1class Machine
2  attr_accessor :filename, :machine_data
3
4  def initialize(filename, machine_data)
5    @filename = filename
6    @machine_data = machine_data
7  end
8
9  def open_file
10    @file = File.open(@filename)
11  end
12
13  def parse_data_each_line
14    @file.read.split("\n")
15  end
16
17  def remodeling_data
18    @machine_data.each do |element|
19    end
20  end
21end

In the above case even though attr_accessor is defined the user is not using it effectively.

The programmer is using instance variables @filename and @machine_data directly.

In an instance of a class the instance variables are available globally in the object. Anywhere in the object any instance method can get hold of any instance variable by just using @name_of_variable.

This behavior of instance variables makes instance variables like a global constant. Any instance method can read it and any instance method can update it.

In the above class notice that method open_file is creating an instance variable @file. And method parse_data is accessing that instance variable.

If we just look at those two methods then they are using @file as a global constant. This is not a good way to write object oriented programs.

Object oriented programming is about accessing the data the right way. And the right way in this case would be by using attr_reader, attr_writer or attr_accessor.

Let's try to fix the above code. First let's see how @file_name and @machine_data are being used. Both of these instance variables are being read. No method is setting value to to it. So there is no need to have attr_accessor. Let's change that to attr_reader and change the code so that @file_name and @machine_data is not directly used.

1class Machine
2 attr_reader :filename, :machine_data
3
4 def initialize(filename, machine_data)
5   @filename = filename
6   @machine_data = machine_data
7 end
8
9 def open_file
10   @file = File.open(filename)
11 end
12
13 def parse_data_each_line
14   @file.read.split("\n")
15 end
16
17 def remodeling_data
18   machine_data.each do |element|
19   end
20 end
21end

Now let's fix how @file is being used. The method open_file is writing to this instance variable and method parse_data is reading this instance variable. So we should use attr_accessor for this.

1class Machine
2 attr_reader :filename, :machine_data
3 attr_accessor :file
4
5 def initialize(filename, machine_data)
6   @filename = filename
7   @machine_data = machine_data
8 end
9
10 def open_file
11   self.file = File.open(filename)
12 end
13
14 def parse_data_each_line
15   file.read.split("\n")
16 end
17
18 def remodeling_data
19   machine_data.each do |element|
20   end
21 end
22end

Please note that in method open_file we need to use self.file =. If we use only file = then Ruby will create a local variable called file.

    ⌘F
      to navigateEnterto select Escto close
      Older
      Newer