Di mana menempatkan metode privat di Ruby?

95

Sebagian besar blog atau tutorial atau buku memiliki metode privat di bagian bawah kelas / modul apa pun. Apakah ini praktik terbaik?

Saya merasa memiliki metode privat jika diperlukan lebih nyaman. Sebagai contoh:

public
def my_method
  # do something
  minion_method
end

private
def minion_method
  # do something
end

public
def next_method
end

Dengan cara ini saya menemukan kode lebih mudah dibaca daripada menggulir ke atas dan ke bawah terus menerus yang sangat menjengkelkan.

Apakah ada yang sangat salah dalam pendekatan ini? Apakah memiliki metode privat di bawah bukan hanya praktik terbaik dan sesuatu yang lain?

ZX12R
sumber
sebenarnya caramu juga tidak buruk. Saya juga mengikuti hal yang sama dalam beberapa kasus, rasanya lebih nyamanprivate def my_method...end
r3bo0t

Jawaban:

131

Praktik terbaik dalam sudut pandang saya adalah pergi secara berurutan dan mendeklarasikan metode Anda tanpa menjaga privasi dalam sudut pandang.

Pada akhirnya, Anda dapat membuat metode apa pun menjadi pribadi hanya dengan menambahkan: private :xmethod

Contoh:

class Example
 def xmethod
 end

 def ymethod
 end

 def zmethod 
 end

 private :xmethod, :zmethod

end

Apakah ini membenarkan pertanyaan Anda?

kiddorails
sumber
19
Saya tidak berpikir ini adalah ide yang bagus dari sudut pandang keterbacaan karena kelas tumbuh semakin lama.
Alexander Suraphel
2
Saya benar-benar berpikir Anda harus mengurutkan metode berdasarkan urutan kepentingan dan berdasarkan apa yang disebut apa ketika semua hal lain tampak sama. Metode privat adalah detail implementasi dan harus menjadi hal terakhir yang dilihat pembaca sehingga termasuk lebih rendah dalam file. Saya setuju dengan komentar di atas bahwa ini tidak akan berfungsi dengan baik dengan file yang lebih besar. Ini seharusnya bukan jawaban yang diterima, ada banyak saran yang lebih baik di halaman ini.
Luke Cowell
58

Ada juga opsi untuk menambahkan privatedefinisi metode sejak Ruby 2.1.

class Example

 def xmethod
 end

 private def ymethod
 end

 private def zmethod 
 end

end

Melihat definisinya, Anda langsung tahu jika suatu metode bersifat pribadi, di mana pun dalam file itu didefinisikan. Ini sedikit lebih mengetik (jika Anda tidak melengkapi otomatis) dan tidak semua defs Anda akan disejajarkan dengan baik.

Dennis
sumber
5
Anda harus menambahkan catatan, bahwa ini tersedia di Ruby 2.1 di mana metode mengembalikan kunci dengan namanya sendiri: bugs.ruby-lang.org/issues/3753
konole
Saya percaya pribadi juga dapat digunakan sebagai blok, alias melampirkan beberapa metode pribadi secara pribadi mulai ... akhir
edx
lihat jawaban @devpuppy di sini untuk catatan tentang melakukan ini dengan metode kelas.
manroe
Menambahkan privatehanya sekali, sebelum ymethod, juga berfungsi. Tidak perlu menambahkannya berkali-kali.
Iulian Onofrei
@IulianOnofrei Jika Anda memiliki metode lain di bawah ini zmethodtanpa private, metode ini tidak akan bersifat pribadi. Jadi, Anda perlu mengulanginya (setidaknya dengan Ruby 2.3).
tsauerwein
52

Seperti yang telah ditunjukkan orang lain, konvensi adalah meletakkan metode privat di bagian bawah, di bawah satu kelas privat. Namun, Anda mungkin juga harus tahu bahwa banyak programmer menggunakan metode indentasi ganda (4 spasi, bukan 2) untuk ini. Alasannya adalah sering kali Anda tidak melihat "pribadi" di editor teks Anda dan menganggapnya sebagai publik. Lihat ilustrasi di bawah ini:

class FooBar

  def some_public_method
  end

  def another_public_method
  end

private

    def some_private_method
    end

    def another_private method
    end

end

Metode ini akan mencegah Anda dari keharusan untuk menggulir ke atas dan ke bawah dan akan membuat programmer lain lebih nyaman dalam kode Anda.

Noah Clark
sumber
4
Ini semua kemarahan ketika saya meninggalkan komentar ini di '12. Saya tidak melihat ini terlalu sering lagi dan itu tidak disukai.
Noah Clark
pribadi juga bisa diformat di dalam begin..endsetelahnya private. Kemudian indentasi dapat diatur secara otomatis oleh editor karena kode di dalam beginis (dalam contoh di atas) secara semantik menjorok ke dalam 4 spasi.
Petrus Repo
Saya mengikuti pendekatan yang sama ... pertama publicdan kemudianprivate
Rahul Goyal
1
Saya belum pernah melihat ini dan saya telah bekerja dengan Ruby sejak 2007. Saya biasanya tidak merekomendasikannya.
Marnen Laibow-Koser
15

Saya pikir metode publik adalah semacam antarmuka objek, dan logis untuk menempatkannya di tempat yang paling menonjol yaitu di bagian atas file.

Flexoid
sumber
5
Ya, letakkan metode publik di tempat yang paling mungkin Anda temukan, biasanya di dekat bagian atas file, dan hal-hal yang mungkin tidak boleh Anda lihat harus terkubur di dekat bagian bawah. Seperti artikel surat kabar ditulis, utamakan hal yang paling penting.
tadman
14

Anda tidak perlu menempatkan publicatau di privateatas setiap metode. Saya biasanya meletakkan semua metode privat saya di bagian bawah kelas saya. Juga, tidak perlu mengatakan secara eksplisit publickarena metode bersifat publik secara default. Sebagai contoh:

class FooBar

  def some_public_method
  end

  def another_public_method
  end

private

  def some_private_method
  end

  def another_private method
  end

end
Kyle Decot
sumber
Silakan baca pertanyaan saya lagi. Telah mengeditnya agar lebih spesifik
ZX12R
1
Ini lebih merupakan konvensi daripada apapun. Apa yang Anda lakukan adalah valid dan jika itu lebih masuk akal bagi Anda maka Anda harus mematuhinya. Saya menemukan konvensi menjadi lebih mudah dibaca tetapi itu mungkin karena itulah cara saya diajari untuk menulisnya jadi saya terbiasa dengannya.
Kyle Decot
apa sebenarnya arti mendeklarasikan metode sebagai "publik" / lakukan?
ZX12R
6

Saya berasal dari latar belakang java dan saya benci harus menggulir untuk melihat jenis metode. Saya pikir itu gila bahwa seseorang tidak dapat menentukan visibilitas metode per metode tanpa kejelekan. Jadi saya akhirnya memberi komentar #privatesebelum setiap metode menyedot dan kemudian menyatakan private :....

akostadinov
sumber
1
dan ruby ​​baru-baru ini bisa private def method...membuatnya lebih bagus
akostadinov
5

Saya tidak suka menentukan publik atau privat untuk setiap metode. Menempatkan semua metode pribadi di bagian bawah memungkinkan saya memiliki satu contoh "pribadi" per file. Saya kira ini masalah selera.

David
sumber
5

Salah satu gayanya adalah mengelompokkan metode bersama sehingga Anda hanya menggunakan privatedan paling banyak protectedsekali per kelas. Gaya lainnya adalah menentukan visibilitas tepat setelah definisi metode:

class Example
  def my_private_method
  end
  private :my_private_method

  def my_public_method
  end
end

Sejak Ruby 2.1.0 defmengembalikan nama metode sebagai simbol, jadi gaya yang lebih ramping dimungkinkan:

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

(Perhatikan bahwa kami menggunakan private_class_methoduntuk metode kelas - jika tidak, kami akan mendapatkannya NameError: undefined methodkarena privatemengharapkan metode instance. Bahkan ketika menggunakannya sebagai makro seperti dalam contoh asli, itu hanya memengaruhi visibilitas metode instance.)

Saya paling suka gaya visibilitas sebaris ini, karena memungkinkan Anda mengatur metode sesuai keinginan. Ini mengurangi risiko menambahkan metode baru di tempat yang salah dan secara tidak sengaja menjadikannya pribadi.

Sedangkan untuk sintaks metode kelas, Anda dapat menanganinya dengan cara ini:

class Example
  private def my_private_method
  end

  class << self
    private def my_private_class_method
    end
  end
end
devpuppy
sumber
ini adalah satu-satunya tempat yang pernah saya lihat menyebutkan private_class_methodpanggilan sebelumnya, dan bagian terakhir tentang menggunakan class << selfblok untuk menghindari penggunaan itu adalah tip yang bagus. Sampai sekarang, saya tidak tahu bahwa metode kelas "nornal" (dideklarasikan dengan def self.foo; endbukannya class << self; def foo; endtidak akan terpengaruh oleh private
penentu
3

Dennis punya jawaban yang tepat, yaitu saat menggunakan ruby> = 2.1, awali def dengan private (or protected, public)

Tapi saya percaya bahwa sekarang juga mungkin untuk menggunakan private sebagai blok seperti:

private begin
   def foo
   end
   def bar
   end
end

def zip
end
edx
sumber
0

Saya biasanya memesan metode saya sebagai berikut:

  1. Pembuat
  2. Metode umum lainnya, dalam urutan abjad
  3. private, ditulis hanya sekali
  4. Metode pribadi, dalam urutan abjad

Saya menggunakan fitur "pergi ke definisi" di editor saya sehingga ini tidak melibatkan banyak pengguliran, dan dalam kasus apa pun, jika kelas cukup besar sehingga pengguliran menjadi masalah, mungkin harus dipecah menjadi beberapa kelas.

Marnen Laibow-Koser
sumber
Saya juga harus menyebutkan bahwa saya biasanya meletakkan metode konversi (seperti to_s) di dekat akhir bagian publik.
Marnen Laibow-Koser