Ruby'de özel yöntemler nereye yerleştirilir?


95

Blogların, öğreticilerin veya kitapların çoğu, herhangi bir sınıfın / modülün altında özel yöntemlere sahiptir. Bu en iyi uygulama mı?

Gerektiğinde özel yöntemlere sahip olmayı daha uygun buluyorum. Örneğin:

public
def my_method
  # do something
  minion_method
end

private
def minion_method
  # do something
end

public
def next_method
end

Bu şekilde, sürekli olarak yukarı ve aşağı kaydırmak yerine kodu daha okunaklı buluyorum ki bu çok rahatsız edici.

Bu yaklaşımda çok kötü bir şey mi var? En altta özel yöntemlere sahip olmak sadece bir en iyi uygulama ve başka bir şey değil mi?


aslında senin yolun da fena değil. Birkaç durumda da aynısını takip ediyorum, daha uygun hissettiriyorprivate def my_method...end
r3bo0t

Yanıtlar:


131

Benim bakış açıma göre en iyi uygulama, sırayla gitmek ve yöntemlerinizi bakış açınızı gizli tutmadan beyan etmektir.

Sonunda, yalnızca ekleyerek herhangi bir yöntemi özel yapabilirsiniz: private :xmethod

Misal:

class Example
 def xmethod
 end

 def ymethod
 end

 def zmethod 
 end

 private :xmethod, :zmethod

end

Bu sorunuzu haklı çıkarıyor mu?


19
Sınıf büyüdükçe ve uzadıkça bunun okunabilirlik açısından harika bir fikir olduğunu düşünmüyorum.
Alexander Suraphel

2
Yöntemleri önem sırasına göre ve diğer her şey eşit göründüğünde neyi çağırdığına göre sıralamanız gerektiğini düşünüyorum. Özel yöntemler, bir uygulama ayrıntılarıdır ve okuyucunun gördüğü en son şey olmalı, bu nedenle dosyanın alt kısımlarına aittir. Bunun daha büyük dosyalarla iyi çalışmayacağı yönündeki yukarıdaki yoruma katılıyorum. Bu kabul edilen cevap olmamalı, bu sayfada çok daha iyi tavsiyeler var.
Luke Cowell

58

privateRuby 2.1'den beri yöntem tanımının başına ekleme seçeneği de vardır .

class Example

 def xmethod
 end

 private def ymethod
 end

 private def zmethod 
 end

end

Tanıma baktığınızda, dosyanın neresinde tanımlanırsa tanımlansın bir yöntemin özel olup olmadığını anında anlarsınız. Bu biraz daha fazla yazmadır (otomatik tamamlamazsanız) ve tüm defe-postalarınız hoş bir şekilde hizalanmayacaktır.


5
Bunun, yöntemlerin kendi adlarıyla anahtar döndürdüğü Ruby 2.1'de mevcut olduğunu eklemiş olmalısınız: bugs.ruby-lang.org/issues/3753
konole

Özelin bir blok olarak da kullanılabileceğine inanıyorum, diğer bir deyişle özel başlangıç ​​... bitiş
edx

Bunu sınıf yöntemleriyle yapmakla ilgili bir not için buradaki @evpuppy yanıtına bakın .
manroe

Öncesine privateyalnızca bir kez eklemek ymethodde işe yarar. Birden çok kez eklemenize gerek yoktur.
Iulian Onofrei

@IulianOnofrei Aşağıda zmethodonsuz başka bir privateyönteminiz olsaydı, bu yöntem özel olmazdı. Yani, tekrar etmelisiniz (en azından Ruby 2.3 ile).
tsauerwein

52

Diğerlerinin daha önce de belirttiği gibi, sözleşme, özel yöntemleri tek bir özel sınıfın altına, en alta koymaktır. Ancak, muhtemelen birçok programcının bunun için çift girintili (2 yerine 4 boşluk) yöntem kullandığını da bilmelisiniz. Bunun nedeni, çoğu zaman metin düzenleyicinizde "özel" kelimesini görmemeniz ve bunların herkese açık olabileceğini varsaymanızdır. Bir örnek için aşağıya bakın:

class FooBar

  def some_public_method
  end

  def another_public_method
  end

private

    def some_private_method
    end

    def another_private method
    end

end

Bu yöntem, yukarı ve aşağı kaydırmanızı engellemeli ve diğer programcıları kodunuzda daha rahat hale getirecektir.


4
Bu yorumu '12'de bıraktığımda tüm öfke buydu. Bunu artık pek sık görmüyorum ve gözden düştü.
Nuh Clark

özel kişiler de begin..endhemen sonra içinde biçimlendirilebilir private. Daha sonra, içindeki kod begin(yukarıdaki örnekte) anlamsal olarak 4 boşlukla girintili olduğundan, girinti düzenleyici tarafından otomatik olarak ayarlanabilir .
Petrus Repo

Aynı yaklaşımı izliyorum ... önce publicve sonraprivate
Rahul Goyal

1
Bunu hiç görmedim ve 2007'den beri Ruby ile çalışıyorum. Genelde tavsiye etmem.
Marnen Laibow-Koser

15

Herkese açık yöntemlerin nesnenin bir çeşit arayüzü olduğunu düşünüyorum ve onları en belirgin yere, yani dosyanın en üstüne yerleştirmek mantıklı.


5
Evet, herkese açık yöntemleri bulma olasılığınızın en yüksek olduğu yere, genellikle dosyanın üst kısmına koyun ve muhtemelen bakmamanız gereken şeyler en altına gömülmelidir. Bir gazete yazısı yazılır gibi, en önemli şeyleri ilk sıraya koyun.
tadman

14

Her yöntemi koymanıza publicveya privateüstüne koymanıza gerek yoktur . Genelde tüm özel yöntemlerimi sınıfımın altına koyarım. Ayrıca, publicyöntemlerin varsayılan olarak genel olduğunu açıkça belirtmek zorunda değilsiniz . Örneğin:

class FooBar

  def some_public_method
  end

  def another_public_method
  end

private

  def some_private_method
  end

  def another_private method
  end

end

Lütfen sorumu tekrar okuyun. Daha spesifik olması için düzenledik
ZX12R

1
Her şeyden çok bir kongre. Yaptığınız şey geçerlidir ve size daha mantıklı geliyorsa, ona bağlı kalmalısınız. Konvansiyonu daha okunaklı buluyorum ama bu muhtemelen bana onu yazmamın nasıl öğretildiğidir, bu yüzden alıştım.
Kyle Decot

Bir yöntemi "genel" olarak ilan etmek aslında ne anlama geliyor / ne yapıyor?
ZX12R

6

Java arka planından geliyorum ve yöntem türünü görmek için kaydırmak zorunda kalmaktan nefret ediyorum. Bence çirkinlik olmadan yöntem başına yöntem görünürlüğünü belirleyememek delilik. Bu yüzden #privateher emiş yönteminden önce bir yorum koyup sonra beyan ettim private :....


1
ve son yakut private def method...daha güzel olmasını sağlayabilir
akostadinov

5

Her yöntem için genel veya özel olarak belirtmek zorunda kalmayı sevmiyorum. Tüm özel yöntemleri en alta koymak dosya başına tek bir "özel" örneğine sahip olmamı sağlar. Sanırım bu bir zevk meselesi.


5

Bir stil, yöntemleri birlikte gruplamaktır, böylece yalnızca privateve protectedsınıf başına en fazla bir kez kullanırsınız . Diğer bir stil, yöntem tanımından hemen sonra görünürlüğü belirlemektir:

class Example
  def my_private_method
  end
  private :my_private_method

  def my_public_method
  end
end

Ruby 2.1.0'dan itibaren def, yöntem adını bir sembol olarak döndürür, bu nedenle daha akıcı bir stil mümkündür:

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

(Not kullandığımız bu private_class_methodsınıf yöntemleri için - aksi takdirde biz alırdım NameError: undefined methodberi privatebeklentiden bir örnek yöntemi Yalnızca örnek yöntemlerde görünürlüğünü etkileyen özgün örnekteki gibi bir makro olarak kullanmaktan bile..)

Yöntemleri istediğiniz gibi düzenlemenize izin verdiği için bu satır içi görünürlük stilini en çok seviyorum. Yanlış yere yeni bir yöntemin eklenmesi ve yanlışlıkla özel hale getirilmesi riskini azaltır.

Sınıf yöntemi söz dizimine gelince, bunun yerine şu şekilde halledebilirsiniz:

class Example
  private def my_private_method
  end

  class << self
    private def my_private_class_method
    end
  end
end

Bu, daha private_class_methodönce çağrının bahsettiğini gördüğüm tek yer ve class << selfonu kullanmaktan kaçınmak için bloğu kullanmanın son kısmı iyi bir ipucu. Şimdiye kadar, "nornal" sınıf yöntemlerinin ( belirteçten etkilenmeyeceği def self.foo; endyerine ile bildirildiğini bilmiyordum .class << self; def foo; endprivate
manroe

3

Dennis'in mükemmel cevabı vardı, yani ruby> = 2.1 kullanırken, sadece def'e özel (veya korumalı, genel) önekini ekleyin

Ancak şu anda olduğu gibi özeli bir blok olarak kullanmanın da mümkün olduğuna inanıyorum:

private begin
   def foo
   end
   def bar
   end
end

def zip
end

0

Yöntemlerimi genellikle şu şekilde sıralarım:

  1. İnşaatçı
  2. Alfabetik sırayla diğer genel yöntemler
  3. private, sadece bir kez yazılmış
  4. Alfabetik sırayla özel yöntemler

Editörümde "tanıma git" özelliklerini kullanıyorum, böylece bu çok fazla kaydırma içermiyor ve her durumda, sınıf kaydırma işleminin sorunlu hale gelmesine yetecek kadar büyükse, muhtemelen birkaç sınıfa bölünmelidir.


Ayrıca, genellikle dönüştürme yöntemlerini (örneğin to_s) halka açık bölümün sonuna yakın bir yere koyduğumu da belirtmeliyim .
Marnen Laibow-Koser
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.