+1

Instance variable và class variable - Instance variable và class instance variable trong Ruby

Hello các bác, "nại nà iem đêy" 🤡

Chắc khi các bác học về Ruby cũng đã hiểu khái niệm class variable và instance variable rồi. Cách thức hoạt động của nó như thế nào, phạm vi hoạt động ra sao. Cơ mà trong instance variable lại chia ra thành 2 kiểu đó là class instance và object instance. Giờ thấy rối não chưa 🤡. Bài viết hôm nay của em sẽ giải thích về 3 loại variables ở trên, phạm vi hoạt động của nó như thế nào.

1. Instance variable

Instance variable được khai báo với syntax như sau @ + variable_name, chẳng hạn như @product. Instance variable chỉ hoạt động trong phạm vi object của nó. Các instance variables của object này độc lập với instance variables của object kia.

1.a Object instance variable

Object instance variable là instance variable được khai báo trong instance method. Nó có thể được hoạt động ở bất kì instance method nào của object đó.

class Product
  def initialize(name)
    @name = name
  end
  
  def name
    @name
  end
  
  def set_name(value)
    @name = value
  end
end

product1 = Product.new("Audi")
product1.name # => Audi
product2 = Product.new("Mercedes")
product2.name # => Mercedes
product2.set_name("Honda")
product2.name # => Honda
product1.name # => Audi

Có thể thấy, dù product1product2 đều có instance là @name, nhưng 2 instances này là độc lập với nhau. Việc thay đổi @name của product2 không hề gây ảnh hưởng đến @name của @name của product1

1.b Class instance variable

Trong Ruby, một class thực chất cũng chỉ là một object của class Class. Và class instance variables cũng KHÔNG phải object instance variables. Các class instances chỉ hoạt động trong các class method. Vì thế, @name được khai báo trong instance method không phải là @name được khai báo trong class method.

class Product
  def initialize(name)
    @name = name
  end
  
  def name
    @name
  end
  
  def self.name
    @name
  end
  
  def self.set_name(value)
    @name = value
  end 
end

object_product = Product.new("Audi")
object_product.name # => Audi
Product.name # => nil
Product.set_name("Liberty")
Product.name # => Liberty
object_product.name # => Audi

Như ví dụ trên, dù @name đã được khai báo ở object_product nhưng khi gọi method Product.name thì kết quả trả về là nil. Vì dù nó có trùng tên biến, nhưng thực tế 2 instances này lại nằm trên 2 vùng nhớ khác nhau được quản lý bởi 2 object khác nhau.

2. Class variable

Class variable được khai báo với prefix @@. Ví dụ: @@class_variable, @@status. Nó có thể hoạt động trong toàn bộ phạm vi class mà nó được khai báo và cả các class kế thừa. Class variable được chia sẻ với tất cả object của class đó

 class Product
  @@name = "BWM"
  
  def self.name
    @@name
  end

  def self.set_name(value)
    @@name = value
  end

  def name
    @@name
  end

  def set_name(value)
    @@name = value
  end 
 end

Product.name # => BWM
object_product = Product.new
object.name # => BWM
Product.set_name("Yamaha")
Product.name # => Yamaha
object_product.name # => Yamaha
object_product.set_name("Honda")
Product.name # => Honda

Có một lưu ý: class variable hoạt động trong cả các class kế thừa. Nghĩa là các class con của Product cũng sẽ có thể sử dụng hoặc thay đổi giá trị của @@name được khai báo ở class Product. Vì thế hãy cân nhắc khi sử dụng kiểu variable này

Tổng kết

Hiểu được phạm vi hoạt động của các loại variable trong class một một điều rất quan trọng. Nó giúp chúng ta tránh được các bug gây ra do khó kiểm soát được phạm vi hoạt động của variable.

Cảm ơn các bác đã đọc hết bài viết của em, nếu các bác có ý kiến gì thì cứ nhiệt tình đóng góp để em cải thiện thêm nhé.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí