Truy cập biến cá thể từ bên ngoài lớp


82

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:


148

Có, bạn có thể sử dụng instance_variable_getnhư 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_gettrong 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 .


6
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.
Andrew Marshall

@knut chúng ta không thể làm điều này như h = Hello.newh.method1h.hello?
nik7

3
@nlingutla Bạn có thể xác định một accessor vớiattr_reader :hello
Knut

Sẽ không phải alias my_hello hello, không phải alias :my_hello :hello?
Vụ kiện của Fund Monica

1
Đối với tôi, điều này là tuyệt vời cho thông số kỹ thuật, nơi bạn không muốn công khai điều gì đó.
baash

20

Bạn cũng có thể thực hiện điều này bằng cách gọi attr_readerhoặc attr_accessornhư 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_readersẽ tạo ra một getterbiến đã cho:

h = Hello.new
p h.hello        #"pavan"

Việc gọi attr_accessorsẽ tạo getterAND a settercho 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_readerattr_accessorphù hợp. Chỉ sử dụng attr_accessorkhi bạn cần getterAND a settervà sử dụng attr_readerkhi bạn chỉ cầngetter

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.