Nếu một biến cá thể thuộc về một lớp, tôi có thể truy cập trực tiếp vào biến cá thể (ví dụ @hello
) bằng cách sử dụng cá thể lớp không?
class Hello
def method1
@hello = "pavan"
end
end
h = Hello.new
puts h.method1
Câu trả lời:
Có, bạn có thể sử dụng instance_variable_get
như thế này:
class Hello
def method1
@hello = "pavan"
end
end
h = Hello.new
p h.instance_variable_get(:@hello) #nil
p h.method1 #"pavan" - initialization of @hello
p h.instance_variable_get(:@hello) #"pavan"
Nếu biến không được xác định (lần gọi đầu tiên instance_variable_get
trong ví dụ của tôi), bạn sẽ nhận được nil
.
Như Andrew đã đề cập trong bình luận của mình:
Bạn không nên đặt điều này làm cách mặc định để truy cập các biến cá thể vì nó vi phạm tính đóng gói.
Một cách tốt hơn là xác định một trình truy cập:
class Hello
def method1
@hello = "pavan"
end
attr_reader :hello
end
h = Hello.new
p h.hello #nil
p h.method1 #"pavan" - initialization of @hello
p h.hello #"pavan"
Nếu bạn muốn có thêm một tên phương thức, bạn có thể bí danh các accessor: alias :my_hello :hello
.
Và nếu lớp không được xác định trong mã của bạn, nhưng trong một viên đá quý: Bạn có thể sửa đổi các lớp trong mã của mình và chèn các hàm mới vào các lớp .
h = Hello.new
và h.method1
và h.hello
?
attr_reader :hello
alias my_hello hello
, không phải alias :my_hello :hello
?
Bạn cũng có thể thực hiện điều này bằng cách gọi attr_reader
hoặc attr_accessor
như thế này:
class Hello
attr_reader :hello
def initialize
@hello = "pavan"
end
end
hoặc là
class Hello
attr_accessor :hello
def initialize
@hello = "pavan"
end
end
Việc gọi attr_reader
sẽ tạo ra một getter
biến đã cho:
h = Hello.new
p h.hello #"pavan"
Việc gọi attr_accessor
sẽ tạo getter
AND a setter
cho biến đã cho:
h = Hello.new
p h.hello #"pavan"
h.hello = "John"
p h.hello #"John"
Như bạn có thể hiểu, sử dụng attr_reader
và attr_accessor
phù hợp. Chỉ sử dụng attr_accessor
khi bạn cần getter
AND a setter
và sử dụng attr_reader
khi bạn chỉ cầngetter