Biến thể hiện không hiển thị bên ngoài lớp học.
class MyClass
def initialize
@message = "Hello"
end
end
msg = MyClass.new
@message
#==> nil # This @message belongs to the global object, not msg
msg.message
#==> NoMethodError: undefined method `message'
[email protected]
#==> SyntaxError: syntax error, unexpected tIVAR
Bây giờ, bạn luôn có thể làm điều này:
msg.instance_eval { @message }
Nhưng đó là vụng về và cheatish. Poking quanh lớp của người khác có thể là giáo dục, nhưng mã khách hàng của bạn không nên làm điều đó nếu bạn muốn nhận được kết quả đáng tin cậy. Mặt khác, nếu bạn muốn khách hàng có thể xem các giá trị đó, đừng làm cho họ sử dụng instance_eval
; thay vào đó, xác định một phương pháp mà hiện các trick:
class MyClass
def message
return @message
end
end
msg.message
# ==> "Hello"
Bởi vì bạn thường xuyên muốn làm điều đó, Ruby cung cấp một phím tắt để làm cho nó dễ dàng hơn. Mã bên dưới có kết quả chính xác giống như mã ở trên:
class MyClass
attr_reader :message
end
Đó không phải là một loại biến mới; nó chỉ là một cách viết tắt để xác định phương pháp. Bạn có thể xem msg.methods
và thấy rằng nó hiện có phương thức message
.
Bây giờ, điều gì xảy ra nếu bạn muốn cho phép người ngoài không chỉ thấy giá trị của một biến mẫu, mà còn thay đổi giá trị đó? Cho rằng, bạn phải xác định một phương pháp khác để chuyển nhượng, với một =
trong tên:
class MyClass
def message=(new_value)
@message = new_value
end
end
msg.message = "Good-bye"
msg.message
# ==> "Good-bye"
Lưu ý rằng toán tử gán là bán huyền diệu ở đây; mặc dù có khoảng cách giữa msg.message
và =
, Ruby vẫn biết gọi phương thức message=
. Các toán tử kết hợp như +=
và như vậy sẽ kích hoạt các cuộc gọi đến phương thức.
lần nữa, đây là một thiết kế thông thường, vì vậy của Ruby cung cấp một phím tắt cho nó, quá:
class MyClass
attr_writer :message
end
Bây giờ, nếu bạn sử dụng attr_writer
bởi chính nó, bạn sẽ có được một thuộc tính có thể được sửa đổi, nhưng chưa từng thấy . Có một số trường hợp sử dụng lẻ mà đó là những gì bạn muốn, nhưng hầu hết thời gian, nếu bạn định cho phép người ngoài sửa đổi biến, bạn cũng muốn họ có thể đọc nó. Thay vì phải khai báo cả một attr_reader
và một attr_writer
, bạn có thể tuyên bố cả hai cùng một lúc như vậy:
class MyClass
attr_accessor :message
end
Một lần nữa, đây chỉ là một shortcut để xác định phương pháp cho phép bạn có được ở các instance variable từ bên ngoài lớp học.
'attr_accessor' sẽ tạo một biến mẫu, phương thức _plus_ để đọc và viết biến mẫu. –
Thực ra, @AlexWayne, 'attr_accessor' chỉ khai báo các phương thức. Các biến cá thể không phải được khai báo; chúng sẽ trở thành hiện hữu khi bạn cố truy cập chúng (và giá trị của chúng là 'nil' nếu truy cập đầu tiên đó là đọc thay vì viết). –