2017-03-21 18 views
7

Đây là một trường hợp thú vị mà tôi không thể giải thích được. Có vẻ như những người định cư riêng tư 'kiểu' riêng tư, nhưng đôi khi có những ngoại lệ cho điều đó. phương pháp tư nhân thường xuyên dường như hành xử khác nhau để setters tin:Tại sao những người định cư riêng tư hành xử khác với các phương pháp riêng tư khác?

class TestClass 
    def do 
    self.foo = :bar # fine 
    self.baz  # error 
    end 

    private 

    def foo=(other) 
    @foo = other 
    end 

    def baz 
    end 
end 

TestClass.new.do 

Đoạn mã trên bộ @foo tốt, dù đã được kêu gọi một rõ ràng self. Sau đó, nó không gọi #baz, bởi vì #baz là một phương pháp riêng tư.

Có chuyện gì với điều này?

+1

Thông thường tôi sẽ gọi 'baz' mà không sử dụng tiền tố' self' và điều đó sẽ hoạt động trong trường hợp này. Nhưng tôi nhận ra rằng không trả lời câu hỏi trực tiếp của bạn. – moveson

Trả lời

4

Private setters là đặc biệt bởi vì nếu không họ có thể không được gọi tại tất cả:

foo = :bar 

giao cho biến cục bộ foo, nó không gửi tin nhắn foo=.

Lưu ý rằng người định cư không phải là những thứ duy nhất không thể gọi mà không có người nhận rõ ràng. [email protected], [email protected], !, ~, [], []=, +, -, *, /, %, &, |, ^, **, <<, >>, ==, ===, =~, !~, !=, <, >, <=, >=, <=> và có thể một số người khác mà tôi quên cũng không thể được gọi mà không có người nhận rõ ràng. Và sau đó có những thứ như +=, <<= và cứ tiếp tục như vậy.

Có cần phải có ngoại lệ cho tất cả những điều đó. Thật không may, chỉ có một số ngoại lệ đối với một số trong số đó.

Nó đã được đề xuất để thay đổi các quy tắc cho private từ

Chỉ có thể được gọi mà không cần một máy thu rõ ràng, ngoại trừ [danh sách dài các ngoại lệ này là thực sự phức tạp, và vẫn chưa hoàn thành].

để

Chỉ có thể được gọi mà không cần một máy thu rõ ràng hoặc đen đặc biệt biến self như người nhận.

giữ nguyên tất cả các thuộc tính hiện tại của định nghĩa (điều quan trọng nhất là nó có thể được xác định tĩnh tại thời gian phân tích cú pháp).

But so far, nothing has come of it.

1

Nếu bạn không sử dụng self khi sử dụng phương thức setter, thay vào đó nó sẽ gán giá trị cho biến cục bộ. More details.

Trong đoạn mã dưới đây, tôi đã gỡ bỏ self từ việc chuyển nhượng để foo, và bạn sẽ nhìn thấy setter không được sử dụng b/c @foonil:

def do 
    foo = :bar # fine 
    baz  # error 
    puts @foo # prints nil 
    puts foo # prints 'bar' 
    end 
1

Điều đó khá nhiều như thế nào private hoạt động và đó là sự khác biệt chính giữa các phương pháp privateprotected bằng ruby. Bạn không thể gọi các phương thức private ví dụ về lớp học, ngay cả trong lớp đó, trong khi protected cho phép điều đó.

Các vấn đề liên quan