Qu’est-ce que Ruby a que Python n’a pas, et vice versa ?

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

Il y a beaucoup de discussions sur Python contre Ruby, et je les trouve toutes complètement inutiles, car elles expliquent toutes pourquoi la fonctionnalité X est nul dans le langage Y, ou que le langage Y n'a pas X, bien qu'en fait il Je sais aussi exactement pourquoi je préfère Python, mais c'est aussi subjectif, et cela n'aiderait personne à choisir, car ils pourraient ne pas avoir les mêmes goûts que moi en matière de développement.

Ce serait donc être intéressant d'énumérer les différences, objectivement. Donc pas de lambdas de "Python". Expliquez plutôt ce que les lambdas de Ruby peuvent faire que Python ne peut pas. Pas de subjectivité. Un exemple de code est bon !

N'ayez pas plusieurs différences dans une réponse, s'il vous plaît. Et votez pour ceux que vous savez être corrects, et vers le bas ceux que vous savez sont incorrects (ou subjectifs). De plus, les différences de syntaxe ne sont pas intéressantes. Nous savons que Python fait avec l'indentation ce que Ruby fait avec les parenthèses et les extrémités, et que @ est appelé self en Python.

MISE À JOUR : Ceci est maintenant un wiki communautaire, nous pouvons donc ajouter les grandes différences ici.

Ruby a une référence de classe dans le corps de la classe

Dans Ruby, vous avez déjà une référence à la classe (self) dans le corps de la classe. En Python, vous n'avez pas de référence à la classe tant que la construction de la classe n'est pas terminée.

Un exemple :

class Kaka met self end 

self dans ce cas est la classe, et ce code afficherait "Kaka". Il n'y a aucun moyen d'imprimer le nom de la classe ou d'accéder d'une autre manière à la classe à partir du corps de la définition de classe en Python (en dehors définitions de méthodes).

Toutes les classes sont modifiables en Ruby

Cela vous permet de développer des extensions aux classes principales. Voici un exemple d'extension rails :

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

Python (imaginez qu'il n'y avait pas de "". méthodes startswith) :

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

Vous pourrait l'utiliser sur n'importe quelle séquence (pas seulement des chaînes). Pour l'utiliser, vous devez l'importer explicitement, par exemple, depuis some_module import starts_with.

Ruby a des fonctionnalités de script de type Perl

Ruby a des expressions régulières de première classe, des variables $, la boucle d'entrée ligne par ligne awk/perl et d'autres fonctionnalités qui le rendent plus adapté à l'écriture de petits scripts shell qui suppriment les fichiers texte ou agissent comme code de colle pour d'autres programmes.

Ruby a des continuations de première classe

Grâce à l'instruction callcc. En Python, vous pouvez créer des continuations par diverses techniques, mais il n'y a pas de support intégré au langage.

Ruby a des blocs

Avec l'instruction "do", vous pouvez créer un multi- ligne fonction anonyme dans Ruby, qui sera transmise en tant qu'argument dans la méthode devant do, et appelée à partir de là. En Python, vous le feriez plutôt en passant une méthode ou avec des générateurs.

Ruby :

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

Python (les blocs Ruby correspondent à différentes constructions en Python) :

avec amethod() comme ici : # `amethod() est un gestionnaire de contexte many=lines+of+code goes(here) 

Or

for here in amethod() : # `amethod()` est un nombre itérable de plusieurs=lignes+de+code va (ici) 

Ou

def fonction(ici) : plusieurs =lines+of+code va(ici) amethod(function) # `function` est un callback 

Fait intéressant, la déclaration pratique en Ruby pour appeler un bloc est appelée "yield", qui en Python va créer un générateur.

Ruby :

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

Python :

def themethod() : donne 5 pour foo in themethod() : print foo 

Bien que les principes soient différents, le résultat est étonnamment similaire.

Ruby prend en charge plus facilement la programmation de style fonctionnel (de type pipe)

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

Python :

descriptions = (f.description() pour f dans mylist) " ".join(filter(len, descriptions)) 

Python a des générateurs intégrés (qui sont utilisés comme des blocs Ruby, comme indiqué ci-dessus)

Python prend en charge les générateurs dans le langage. Dans Ruby 1.8, vous pouvez utiliser le module générateur qui utilise des continuations pour créer un générateur à partir d'un bloc. Ou, vous pouvez simplement utiliser un bloc/proc/lambda ! De plus, dans Ruby 1.9, les fibres sont et peuvent être utilisées comme générateurs, et la classe Enumerator est un générateur intégré 4

docs.python. org a cet exemple de générateur :

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

Comparez cela avec les exemples de blocs ci-dessus.

Python a une gestion flexible de l'espace de noms

Dans Ruby, lorsque vous importez un fichier avec require, toutes les choses définies dans ce fichier se retrouveront dans votre espace de noms global. Cela provoque une pollution de l'espace de noms. La solution à cela est les modules Rubys. Mais si vous créez un espace de noms avec un module, vous devez utiliser cet espace de noms pour accéder aux classes contenues.

En Python, le fichier est un module, et vous pouvez importer ses noms contenus avec du module import *, polluant ainsi l'espace de noms si vous le souhaitez. Mais vous pouvez également importer uniquement les noms sélectionnés avec du module importer un nom, un autre ou vous pouvez simplement importer lemodule puis accéder aux noms avec lemodule.aname. Si vous voulez plus de niveaux dans votre espace de noms, vous pouvez avoir des packages, qui sont des répertoires avec des modules et un fichier __init__.py.

Python a des docstrings

Docstrings sont des chaînes qui sont attachées à des modules, des fonctions et des méthodes et qui peuvent être introspectées au moment de l'exécution. Cela aide à créer des éléments tels que la commande help et la documentation automatique.

def frobnicate(bar): """frobnicate prend une barre et la frobnicate >>> bar = Bar( ) >>> bar.is_frobnicated() False >>> frobnicate(bar) >>> bar.is_frobnicated() True """ 

Ruby "s équivalents sont similaires à javadocs et situés au-dessus de la méthode plutôt qu'à l'intérieur de celle-ci. Ils peuvent être récupérés lors de l'exécution à partir des fichiers en utilisant la méthode 1.9"s #source_location exemple d'utilisation

Python a un héritage multiple

Ruby n'en a pas ("à dessein" -- voir Site Web de Ruby, voir ici comment il "se fait en Ruby). Il réutilise le concept de module comme un type de classes abstraites.

Python a des compréhensions list/dict

Python :

res = [x* x pour x dans la plage (1, 10)] 

Ruby :

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

Python :

>>> (x*x pour x dans la plage(10)) <objet générateur <genexpr> à 0xb7c1ccd4> ; >>> liste(_) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 

Rubis :

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

Python 2.7+ :

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

Ruby :

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

Python a des décorateurs

Des choses similaires aux décorateurs peuvent également être créées dans Ruby, et on peut également affirmer qu'ils ne sont pas aussi nécessaires qu'en Python.

Différences de syntaxe

Ruby nécessite "end" ou "}" pour fermer toutes ses portées, tandis que Python utilise uniquement les espaces blancs. Il y a eu des tentatives récentes dans Ruby pour autoriser l'indentation des espaces uniquement http://github.com /michaeledgar/sans couture