Ruby Access Control (private)
Bài đăng này đã không được cập nhật trong 3 năm
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
All rights reserved