Ruby’de Python’da olmayan ve bunun tersi ne var?

| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |

Python ile Ruby arasında pek çok tartışma var ve bunların hepsini tamamen yararsız buluyorum, çünkü hepsi X özelliğinin Y dilinde neden berbat olduğunu veya Y dilinde X'in olmadığını iddia ediyor, ancak aslında bu var. Python'u neden tercih ettiğimi de tam olarak biliyorum, ancak bu aynı zamanda özneldir ve geliştirme konusunda benimkiyle aynı zevklere sahip olmayabileceklerinden kimsenin seçim yapmasına yardımcı olmaz.

Bu nedenle olur. farklılıkları nesnel olarak listelemek ilginç olabilir, yani hiçbir "Python"un lambdaları berbat değildir". Bunun yerine Ruby'nin lambdalarının neler yapabileceğini Python'un yapamayacağını açıklayın. Öznellik yok. Örnek kod iyidir!

Bir cevapta birkaç farklılık olmasın, lütfen. Ve doğru olduğunu bildiklerinizi oylayın ve yanlış olduğunu (veya öznel olduğunu) bildiklerinizi azaltın. Ayrıca, sözdizimindeki farklılıklar ilginç değildir. Ruby'nin parantez ve sonlarla yaptığını Python'un girintili olarak yaptığını ve Python'da @'nin self olarak adlandırıldığını biliyoruz.

GÜNCELLEME: Bu artık bir topluluk wiki'sidir, dolayısıyla büyük farkları buraya ekleyebiliriz.

p>

Ruby'nin sınıf gövdesinde bir sınıf referansı var

Ruby'de, sınıf gövdesinde zaten sınıfa (self) bir referansınız var. Python'da sınıf inşası bitene kadar sınıfa referansınız olmaz.

Bir örnek:

class Kaka self end koyar 

self bu durumda sınıftır ve bu kod "Kaka" yazdırır.Sınıf adını yazdırmanın veya başka yollarla Python'daki sınıf tanım gövdesinden (dışarıdan) sınıfa erişmenin bir yolu yoktur. yöntem tanımları).

Ruby'de tüm sınıflar değiştirilebilir

Bu, çekirdek sınıflar için uzantılar geliştirmenizi sağlar. İşte bir Rails uzantısı örneği:

 class String def start_with?(other) head = self[0, other.length] head == other end end 

Python (hiçbir "" olmadığını düşünün. startwith yöntemi):

def start_with(s, prefix): return s[:len(prefix)] == prefix 

Sen herhangi bir dizide kullanabilir (sadece dizelerde değil). Kullanmak için onu açıkça içe aktarmalısınız, örneğin, some_module'den import start_with.

Ruby'nin Perl benzeri komut dosyası oluşturma özellikleri vardır

Ruby birinci sınıf normal ifadelere, $-değişkenlerine, awk/Perl satır satır giriş döngüsüne ve onu metin dosyalarını karıştıran veya diğer programlar için yapıştırıcı kod görevi gören küçük kabuk komut dosyaları yazmaya daha uygun hale getiren diğer özelliklere sahiptir.

Ruby'nin birinci sınıf devamları var

calcc ifadesi sayesinde. Python'da çeşitli tekniklerle devamlar oluşturabilirsiniz, ancak dilde yerleşik bir destek yoktur.

Ruby'nin blokları vardır

"do" deyimi ile çoklu bir oluşturabilirsiniz. do önündeki yönteme argüman olarak iletilecek ve oradan çağrılacak olan Ruby'de satır anonim işlevi. Python'da bunu ya bir yöntem ileterek ya da oluşturucularla yapardınız.

Ruby:

method { |burada| many=lines+of+code (burada) } 

Python (Ruby blokları Python'da farklı yapılara karşılık gelir):

amethod() ile burada: # `ametod() bir bağlam yöneticisidir many=lines+of+code gider(burada) 

Veya

burada amethod() : # `ametod()` yinelenebilir bir çok=satır++kodu gider(burada) 

Veya

def işlevi(burada): çok =lines+of+code gider(burada) amethod(function) # `function` bir geri aramadır 

İlginç bir şekilde, Ruby'de bir bloğu çağırmak için uygunluk ifadesine "verim" denir. Python'da bir üreteç oluşturacaktır.

Ruby:

def tema yöntemi verim 5 son tema yöntemi do |foo| puts foo end 

Python:

def themethod(): themethod() içinde foo için verim 5: print foo 

İlkeler farklı olsa da, sonuç çarpıcı biçimde benzer.

Ruby, işlevsel stil (boru benzeri) programlamayı daha kolay destekler

myList.map(& :description).reject(&:empty?).join(" ") 

Python:

descriptions = (f.description() için) f in mylist) " ".join(filter(len, descriptions)) 

Python'un yerleşik jeneratörleri vardır (yukarıda belirtildiği gibi Ruby blokları gibi kullanılır)

Python'un dilde jeneratör desteği vardır. Ruby 1.8'de, bir bloktan bir jeneratör oluşturmak için süreklilik kullanan jeneratör modülünü kullanabilirsiniz. Veya sadece bir blok/proc/lambda kullanabilirsiniz! Ayrıca, Ruby 1.9'da Fiberler jeneratörlerdir ve jeneratörler olarak kullanılabilirler ve Enumerator sınıfı yerleşik bir jeneratördür 4

docs.python. org'da şu oluşturucu örneği var:

def reverse(data): index in range(len(data)-1, -1, -1): verim data[index] 

Bunu yukarıdaki blok örnekleriyle karşılaştırın.

Python esnek ad alanı yönetimine sahiptir

Ruby'de, require, o dosyada tanımlanan her şey global ad alanınızda sona erecektir. Bu ad alanı kirliliğine neden olur. Bunun çözümü Rubys modülleridir. Ancak bir modül ile bir ad alanı oluşturursanız, o zaman bu ad alanını içerilen sınıflara erişmek için kullanmanız gerekir.

Python'da dosya bir modüldür ve içerdiği adları ile içe aktarabilirsiniz. themodule import *'dan, böylece isterseniz ad alanını kirletebilirsiniz. Ama aynı zamanda from themodule import aname, other ile seçilmiş isimleri içe aktarabilir veya basitçe module import ve ardından themodule.aname. Ad alanınızda daha fazla seviye istiyorsanız, modüller ve bir __init__.py dosyası içeren dizinler olan paketleriniz olabilir.

Python'un belge dizeleri var

Belge dizeleri modüllere, işlevlere ve yöntemlere eklenen ve çalışma zamanında iç gözlemlenebilen dizelerdir. Bu, help komutu ve otomatik belgeler gibi şeyler oluşturmaya yardımcı olur.

def frobnicate(bar): """frobnicate bir çubuk alır ve onu frobnicate >>> bar = Bar( ) >>> bar.is_frobnicated() Yanlış >>> frobnicate(bar) >>> bar.is_frobnicated() True """ 

Ruby "s eşdeğeri javadocs'a benzerdir ve içinde yerine yöntemin üzerinde bulunur. Çalışma zamanında 1.9"s Method#source_location örnek kullanım

Python'da birden fazla miras var

Ruby yok ("bilerek" -- bkz. Ruby"nin web sitesi, buradan nasıl olduğunu görün "Ruby'de yapılır). Modül kavramını bir tür soyut sınıf olarak yeniden kullanır.

Python'un liste/dikt anlayışları vardır

Python:

res = [x* x için x in range(1, 10)] 

Ruby:

res = (0..9).map { |x| x * x } 

Python:

>>> (aralık(10) içindeki x için x*x)) <generator nesnesi <genexpr> 0xb7c1ccd4> >>> list(_) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 

Yakut:

p = proc { |x| x * x } (0..9).map(&p) 

Python 2.7+:

> ������; {1:2, 3:4}.items()} içindeki x,y için {x:str(y*y) {1: "4", 3: "16"} 

Yakut:

>> Hash[{1=>2, 3=>4}.map{|x,y| [x,(y*y).to_s]}] => {1=>"4", 3=>"16"} 

Python'un dekoratörleri var

Dekoratörlere benzer şeyler Ruby'de de oluşturulabilir ve Python'daki kadar gerekli olmadıkları da iddia edilebilir.

Sözdizimi farklılıkları

Ruby tüm kapsamlarını kapatmak için "son" veya "}" gerektirirken Python yalnızca boşluk kullanır. Ruby'de yalnızca boşluk girintisine izin vermek için son zamanlarda girişimlerde bulunuldu http://github.com /michaeledgar/kesintisiz