Đặt các phương thức riêng trong Ruby ở đâu?


95

Hầu hết các blog hoặc hướng dẫn hoặc sách đều có các phương thức riêng tư ở dưới cùng của bất kỳ lớp / mô-đun nào. Đây có phải là cách thực hành tốt nhất?

Tôi thấy có các phương pháp riêng tư và khi cần thiết thuận tiện hơn. Ví dụ:

public
def my_method
  # do something
  minion_method
end

private
def minion_method
  # do something
end

public
def next_method
end

Bằng cách này, tôi thấy mã dễ đọc hơn thay vì cuộn lên và xuống liên tục, rất khó chịu.

Có điều gì đó sai khủng khiếp trong cách tiếp cận này? Có phải việc có các phương pháp riêng ở phía dưới không chỉ là một phương pháp hay nhất mà còn là điều gì khác?


thực ra cách của bạn cũng không tệ. Tôi cũng làm theo như vậy trong vài trường hợp, nó cảm thấy thuận tiện hơnprivate def my_method...end
r3bo0t

Câu trả lời:


131

Thực tiễn tốt nhất theo quan điểm của tôi là đi tuần tự và khai báo các phương pháp của bạn mà không giữ riêng tư theo quan điểm.

Cuối cùng, bạn có thể đặt bất kỳ phương thức nào ở chế độ riêng tư bằng cách thêm: private :xmethod

Thí dụ:

class Example
 def xmethod
 end

 def ymethod
 end

 def zmethod 
 end

 private :xmethod, :zmethod

end

Điều này có biện minh cho câu hỏi của bạn không?


19
Tôi không nghĩ đây là một ý tưởng tuyệt vời theo quan điểm dễ đọc khi lớp học ngày càng dài ra.
Alexander Suraphel

2
Tôi thực sự nghĩ rằng bạn nên sắp xếp các phương pháp theo thứ tự quan trọng và theo thứ gọi là gì khi tất cả những thứ khác có vẻ như nhau. Các phương thức riêng tư là một chi tiết triển khai và phải là thứ cuối cùng mà người đọc nhìn thấy nên thuộc về phần thấp hơn trong tệp. Tôi đồng ý với nhận xét ở trên rằng điều này sẽ không hoạt động tốt với các tệp lớn hơn. Đây không phải là câu trả lời được chấp nhận, có rất nhiều lời khuyên tốt hơn trên trang này.
Luke Cowell

58

Ngoài ra còn có tùy chọn để thêm vào privateđịnh nghĩa phương thức kể từ Ruby 2.1.

class Example

 def xmethod
 end

 private def ymethod
 end

 private def zmethod 
 end

end

Nhìn vào định nghĩa, bạn ngay lập tức biết liệu một phương thức có riêng tư hay không, bất kể nó được định nghĩa ở đâu trong tệp. Đó là một lần gõ nhiều hơn (nếu bạn không tự động hoàn thành) và không phải tất cả các chữ cái của bạn defsẽ được căn chỉnh tốt.


5
Bạn nên có thêm lưu ý, rằng đây là có sẵn trong Ruby 2.1 mà phương pháp trở lại quan trọng với tên riêng của họ: bugs.ruby-lang.org/issues/3753
konole

Tôi tin rằng lon tư nhân cũng được sử dụng như một khối, hay còn gọi là kèm theo một số phương pháp tư nhân ở tư nhân bắt đầu ... cuối
edx

xem câu trả lời của @devpuppy tại đây để biết lưu ý về việc thực hiện điều này với các phương thức lớp.
manroe

privateChỉ thêm một lần, trước ymethod, cũng hoạt động. Không cần phải thêm nó nhiều lần.
Iulian Onofrei

@IulianOnofrei Nếu bạn có một phương thức khác bên dưới zmethodmà không có private, phương thức này sẽ không phải là riêng tư. Vì vậy, bạn cần phải lặp lại nó (ít nhất là với Ruby 2.3).
tsauerwein

52

Như những người khác đã chỉ ra, quy ước là đặt các phương thức private ở dưới cùng, dưới một lớp private. Tuy nhiên, có lẽ bạn cũng nên biết rằng nhiều lập trình viên sử dụng phương pháp thụt lề kép (4 dấu cách thay vì 2) cho việc này. Lý do là đôi khi bạn sẽ không thấy "riêng tư" trong trình soạn thảo văn bản của mình và cho rằng chúng có thể là công khai. Xem hình minh họa bên dưới:

class FooBar

  def some_public_method
  end

  def another_public_method
  end

private

    def some_private_method
    end

    def another_private method
    end

end

Phương pháp này sẽ giúp bạn không phải cuộn lên và cuộn xuống và sẽ giúp các lập trình viên khác thoải mái hơn trong việc viết mã của bạn.


4
Đây là tất cả sự giận dữ khi tôi để lại nhận xét này vào năm '12. Tôi không thấy điều này thường xuyên nữa và nó đã không còn được ưa chuộng.
Noah Clark

private cũng có thể được định dạng bên trong begin..endngay sau đó private. Sau đó, trình soạn thảo có thể đặt tự động thụt lề vì mã bên trong beginlà (trong ví dụ trên) được thụt lề về mặt ngữ nghĩa với 4 dấu cách.
Petrus Repo

Tôi làm theo cùng một cách tiếp cận ... đầu tiên publicvà sau đóprivate
Rahul Goyal

1
Tôi chưa bao giờ thấy điều này và tôi đã làm việc với Ruby từ năm 2007. Nói chung tôi sẽ không giới thiệu nó.
Marnen Laibow-Koser 19/09/19

15

Tôi nghĩ rằng các phương thức công khai là một loại giao diện nào đó của đối tượng, và thật hợp lý khi đặt chúng ở vị trí nổi bật nhất, tức là ở đầu tệp.


5
Có, hãy đặt các phương thức công khai ở nơi bạn có nhiều khả năng tìm thấy chúng nhất, thường là gần đầu tệp và những thứ bạn có thể không nên xem nên được chôn ở gần cuối. Giống như một bài báo được viết, hãy đặt những điều quan trọng nhất lên hàng đầu.
tadman

14

Bạn không cần phải đặt publichoặc privateở trên mỗi phương thức. Tôi thường đặt tất cả các phương thức riêng tư của mình ở cuối lớp. Ngoài ra, không cần phải nói rõ ràng publicvì các phương thức được công khai theo mặc định. Ví dụ:

class FooBar

  def some_public_method
  end

  def another_public_method
  end

private

  def some_private_method
  end

  def another_private method
  end

end

Vui lòng đọc lại câu hỏi của tôi. Đã chỉnh sửa nó để cụ thể hơn
ZX12R

1
Đó là một quy ước hơn bất cứ điều gì. Những gì bạn đang làm là hợp lệ và nếu nó có ý nghĩa hơn với bạn thì bạn nên gắn bó với nó. Tôi thấy quy ước dễ đọc hơn nhưng có lẽ đó là cách tôi được dạy để viết nó nên tôi đã quen với nó.
Kyle Decot

việc khai báo một phương thức là "public" thực sự có nghĩa là gì?
ZX12R

6

Tôi đến từ nền java và tôi ghét phải cuộn để xem loại phương thức. Tôi nghĩ thật điên rồ khi người ta không thể chỉ định khả năng hiển thị phương thức cho mỗi phương thức mà không có sự xấu xí. Vì vậy, tôi đã kết thúc việc đặt một bình luận #privatetrước mỗi phương thức hút và sau đó khai báo private :....


1
và ruby gần đây chỉ có thể đặt private def method...để có nó đẹp hơn
akostadinov

5

Tôi không thích phải chỉ định công khai hoặc riêng tư cho mỗi phương thức. Đặt tất cả các phương thức riêng tư ở dưới cùng cho phép tôi có một trường hợp "riêng tư" cho mỗi tệp. Tôi đoán đó là vấn đề về hương vị.


5

Một kiểu là nhóm các phương thức lại với nhau để bạn chỉ sử dụng privatevà tối đa protectedmột lần cho mỗi lớp. Một kiểu khác là chỉ định khả năng hiển thị ngay sau định nghĩa phương thức:

class Example
  def my_private_method
  end
  private :my_private_method

  def my_public_method
  end
end

Kể từ Ruby 2.1.0 deftrả về tên phương thức dưới dạng một biểu tượng, vì vậy có thể có một kiểu sắp xếp hợp lý hơn:

class Example
  private def my_private_method
  end

  def my_public_method
  end

  protected def my_protected_method
  end

  private_class_method def self.my_private_class_method
  end
end

(Lưu ý rằng chúng tôi sử dụng private_class_methodcho các phương thức lớp - nếu không, chúng tôi sẽ nhận được NameError: undefined methodprivatemong đợi một phương thức cá thể. Ngay cả khi sử dụng nó như một macro như trong ví dụ ban đầu, nó chỉ ảnh hưởng đến khả năng hiển thị của các phương thức cá thể.)

Tôi thích nhất kiểu hiển thị nội tuyến này, vì nó cho phép bạn tổ chức các phương thức theo ý muốn. Nó làm giảm nguy cơ thêm một phương pháp mới vào sai chỗ và vô tình làm cho nó trở nên riêng tư.

Đối với cú pháp phương thức lớp, bạn có thể xử lý nó theo cách này thay thế:

class Example
  private def my_private_method
  end

  class << self
    private def my_private_class_method
    end
  end
end

đây là nơi duy nhất tôi đã thấy đề cập đến private_class_methodcuộc gọi trước đây, và phần cuối cùng về việc sử dụng class << selfkhối để tránh cần sử dụng nó là một mẹo hay. Cho đến bây giờ, tôi không biết rằng các phương thức của lớp "nornal" (được khai báo bằng def self.foo; endthay vì class << self; def foo; endsẽ không bị ảnh hưởng bởi trình privatechỉ định.
manroe

3

Dennis có câu trả lời hoàn hảo, đó là, khi sử dụng ruby> = 2.1, chỉ cần thêm tiền tố def bằng private (hoặc protected, public)

Nhưng tôi tin rằng bây giờ cũng có thể sử dụng private như một khối như trong:

private begin
   def foo
   end
   def bar
   end
end

def zip
end

0

Tôi thường sắp xếp các phương pháp của mình như sau:

  1. Constructor
  2. Các phương pháp công khai khác, theo thứ tự bảng chữ cái
  3. private, chỉ viết một lần
  4. Các phương thức riêng, theo thứ tự bảng chữ cái

Tôi sử dụng các tính năng "đi đến định nghĩa" trong trình soạn thảo của mình để điều này không liên quan đến việc cuộn nhiều và trong mọi trường hợp, nếu lớp đủ lớn khiến việc cuộn trở nên có vấn đề, có lẽ nó nên được chia thành nhiều lớp.


Tôi cũng nên đề cập rằng tôi thường đặt các phương thức chuyển đổi (chẳng hạn như to_s) ở gần cuối phần công khai.
Marnen Laibow-Koser
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.