12/08/2018, 15:36

Ruby Access Control (private)

Bữa mình làm project thì tình cờ thấy hàm private được gọi bởi một class kế thừa, nên mình quyết định viết bài này để tìm hiểu rõ hơn như thế nào! 1. Tính bao đóng trong OOP Được thể hiện qua 3 keywords quen thuộc như hello world, đó là private, protected, public. Ai cũng biết là private ...

Bữa mình làm project thì tình cờ thấy hàm private được gọi bởi một class kế thừa, nên mình quyết định viết bài này để tìm hiểu rõ hơn như thế nào!

1. Tính bao đóng trong OOP

Được thể hiện qua 3 keywords quen thuộc như hello world, đó là private, protected, public. Ai cũng biết là private thì chỉ dùng được trong class của chính nó. Protected thì class kế thừa nó có thể dùng được, hoặc là cùng package ở trong java cũng có thể dùng được. Public thì giống như cái giếng làng, ai cũng có thể múc nước được ^^

Thân em như cái giếng làng Người thanh rửa mặt, người phàm rửa chân

2. Xét qua 1 số ví dụ nhỏ sau

class Y
  def a
    self.x
  end
  private
  def x
    puts "ahihi"
  end
end

Y.new.a

Thì ta bị lỗi NoMethodError ngay ở Y.new.a vì a là private

Nhưng ta xét thêm 1 ví dụ khác nhau sau:

class A
  def main_method
    method1
  end

  private
  def method1
    puts "hello, #{self.class}"
  end
end

class B < A
  def main_method
    method1
  end
end

A.new.main_method
B.new.main_method

Ở đây object của class được new ra và gọi main_method, trong main method lại gọi 1 hàm private, tưởng chừng không được nhưng ai ngờ được thiệt.

Còn class C sau đây gọi thông qua self nên bị lỗi

class C < A
  def main_method
    self.method1
  end
end

C.new.main_method

Ta tìm hiểu thêm 2 định nghĩa sau đây:

3. Implicit receiver và Explicit receiver

Receiver: Bất kỳ lời gọi hàm nào đều có trả về kết quả cho thằng gọi nó, thì đứa được nhận được gọi là receiver

Xem 1 ví dụ sau để phân biệt implicit receiver và explicit receiver

 class Foo
     def foo
        "foo"
     end
     def bar
         self.foo  # explicit receiver - self
         foo # calls the same method on the same object but with implicit receiver since we don't mention it explicitly
     end
  end
  obj = Foo.new
  obj.foo # explicit receiver, `obj`

Trong hàm bar ta thấy sẽ self.foo được gọi bởi receiver là self, quá rõ ráng, nên ta gọi nó là explicit receiver. Còn lời gọi hàm foo ngay sau đó là implicit receiver vì nó không chỉ ra rõ ràng là ai gọi nó.

Để hiểu rõ hơn các bạn có thể xem qua link này. What is the difference between an implicit and explicit receiver?

4. Kết luận

Trong Ruby nó sẽ cho bạn gọi hàm private từ implicit receiver, và không cho đối với explicit receiver.

Ngoài ra các bạn muồn tìm hiểu thêm đối protected thì như thế nào? Nó có giống với private không thì hãy đọc link này nhé. Are Private And Protected Methods Only A Guideline?

                                                 END
0