Cosa ha Ruby che Python non ha e viceversa?

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

Ci sono molte discussioni su Python vs Ruby, e tutte le trovo completamente inutili, perché girano tutte intorno al motivo per cui la funzione X fa schifo nel linguaggio Y, o che affermano che il linguaggio Y non ha X, anche se in realtà lo lo fa. So anche esattamente perché preferisco Python, ma anche questo è soggettivo e non aiuterebbe nessuno a scegliere, poiché potrebbero non avere i miei stessi gusti nello sviluppo in fase di sviluppo.

Sarebbe quindi essere interessante elencare le differenze, oggettivamente. Quindi nessun "lambda di Python fa schifo". Spiega invece cosa possono fare i lambda di Ruby che Python non possono fare. Nessuna soggettività. Il codice di esempio è buono!

Non avere molte differenze in una risposta, per favore. E vota in alto quelli che sai essere corretti e giù quelli che sai essere errati (o soggettivi). Inoltre, le differenze nella sintassi non sono interessanti. Sappiamo che Python fa con l'indentazione ciò che Ruby fa con parentesi e estremità, e che @ è chiamato self in Python.

AGGIORNAMENTO: questo è ora un wiki della comunità, quindi possiamo aggiungere le grandi differenze qui.

p>

Ruby ha un riferimento alla classe nel corpo della classe

In Ruby hai un riferimento alla classe (self) già nel corpo della classe. In Python non hai un riferimento alla classe fino a quando la costruzione della classe non è terminata.

Un esempio:

la classe Kaka mette fine a se stessa 

self in questo caso è la classe e questo codice stamperebbe "Kaka". Non c'è modo di stampare il nome della classe o in altri modi di accedere alla classe dal corpo della definizione della classe in Python (esterno definizioni dei metodi).

Tutte le classi sono modificabili in Ruby

Questo ti permette di sviluppare estensioni alle classi principali. Ecco un esempio di estensione rails:

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

Python (immagina che non ci fosse "". metodo inizia con):

def inizia_con(s, prefisso): return s[:len(prefisso)] == prefisso 

Tu potrebbe usarlo su qualsiasi sequenza (non solo stringhe). Per usarlo dovresti importarlo esplicitamente es. da qualche_modulo l'importazione inizia_con.

Ruby ha funzionalità di scripting simili a Perl

Ruby ha espressioni regolari di prima classe, $-variables, il ciclo di input riga per riga awk/perl e altre funzionalità che lo rendono più adatto alla scrittura di piccoli script di shell che alterano i file di testo o fungono da collante per altri programmi.

Ruby ha continuazioni di prima classe

Grazie all'istruzione callcc. In Python puoi creare continuazioni con varie tecniche, ma non c'è il supporto integrato nel linguaggio.

Ruby ha blocchi

Con l'istruzione "do" puoi creare un multi- linea anonima in Ruby, che verrà passata come argomento nel metodo davanti a do e chiamata da lì. In Python lo faresti invece passando un metodo o con dei generatori.

Ruby:

metodo { |qui| many=lines+of+code goes(here) } 

Python (i blocchi Ruby corrispondono a diversi costrutti in Python):

con amethod() come qui: # `amethod() è un gestore del contesto many=lines+of+code goes(here) 

Oppure

per qui in amethod() : # `method()` è un iterabile many=lines+of+code goes(qui) 

Oppure

def function(qui): many =linee+di+codice va(qui) amethod(funzione) # `funzione` è un callback 

È interessante notare che l'istruzione di convenienza in Ruby per chiamare un blocco è chiamata "yield", che in Python creerà un generatore.

Ruby:

def themethod yield 5 end themethod do |foo| mette foo end 

Python:

def themethod(): yield 5 for foo in themethod(): print foo 

Sebbene i principi siano diversi, il risultato è sorprendentemente simile.

Ruby supporta più facilmente la programmazione in stile funzionale (simile a una pipe)

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

Python:

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

Python ha dei generatori integrati (usati come i blocchi Ruby, come indicato sopra)

Python ha il supporto per i generatori nella lingua. In Ruby 1.8 puoi usare il modulo generatore che usa le continuazioni per creare un generatore da un blocco. Oppure potresti semplicemente usare un block/proc/lambda! Inoltre, in Ruby 1.9 le fibre sono e possono essere utilizzate come generatori e la classe Enumerator è un generatore integrato 4

docs.python. org ha questo esempio di generatore:

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

Confrontalo con gli esempi di blocco sopra.

Python ha una gestione flessibile dello spazio dei nomi

In Ruby, quando importi un file con richiedi, tutte le cose definite in quel file finiranno nel tuo spazio dei nomi globale. Ciò causa l'inquinamento dello spazio dei nomi. La soluzione sono i moduli Rubys. Ma se crei uno spazio dei nomi con un modulo, devi usare quello spazio dei nomi per accedere alle classi contenute.

In Python, il file è un modulo e puoi importarne i nomi contenuti con dal modulo import *, inquinando così lo spazio dei nomi se lo si desidera. Ma puoi anche importare solo i nomi selezionati con from themodule import aname, altro oppure puoi semplicemente importare ilmodule e poi accedere ai nomi con themodule.aname >. Se vuoi più livelli nel tuo spazio dei nomi puoi avere pacchetti, che sono directory con moduli e un file __init__.py.

Python ha docstrings

Docstrings sono stringhe che sono collegate a moduli, funzioni e metodi e possono essere esaminate in fase di esecuzione. Questo aiuta a creare cose come il comando di aiuto e la documentazione automatica.

def frobnicate(bar): """frobnicate prende una barra e la frobnica >>> bar = Bar( ) >>> bar.is_frobnicated() False >>> frobnicate(bar) >>> bar.is_frobnicated() True """ 

Rubino "s equivalenti sono simili a javadocs e si trovano sopra il metodo invece che al suo interno. Possono essere recuperati in fase di esecuzione dai file utilizzando 1.9"s Method#source_location esempio di uso

Python ha un'eredità multipla

Ruby no ("apposta" -- vedi Sito web di Ruby, guarda qui come funziona "s fatto in Ruby). Riutilizza il concetto di modulo come un tipo di classi astratte.

Python ha comprensioni list/dict

Python:

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

Ruby:

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

Python:

>>> (x*x per x nell'intervallo(10)) <oggetto generatore <genexpr> a 0xb7c1ccd4> >>> list(_) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 

Rubino:

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

Python 2.7+:

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

Rubino:

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

Python ha decoratori

Cose simili ai decoratori possono essere create anche in Ruby e si può anche sostenere che "non sono necessari come in Python.

Differenze di sintassi

Ruby richiede "end" o "}" per chiudere tutti i suoi ambiti, mentre Python utilizza solo spazi bianchi. Recentemente in Ruby sono stati tentati di consentire l'indentazione solo degli spazi bianchi http://github.com /michaeledgar/seamless