Ruby a des blocs; Python ne le fait pas.
Python a des fonctions; Ruby ne le fait pas. En Python, vous pouvez prendre n'importe quelle fonction ou méthode et la transmettre à une autre fonction. Dans Ruby, tout est une méthode et les méthodes ne peuvent pas être transmises directement. Au lieu de cela, vous devez les envelopper dans Proc pour les transmettre.
Ruby et Python prennent tous deux en charge les fermetures, mais de manière différente. En Python, vous pouvez définir une fonction dans une autre fonction. La fonction interne a un accès en lecture aux variables de la fonction externe, mais pas un accès en écriture. Dans Ruby, vous définissez les fermetures à l'aide de blocs. Les fermetures ont un accès complet en lecture et en écriture aux variables de la portée externe.
Python a des compréhensions de liste, qui sont assez expressives. Par exemple, si vous avez une liste de nombres, vous pouvez écrire
[x*x for x in values if x > 15]
pour obtenir une nouvelle liste des carrés de toutes les valeurs supérieures à 15. Dans Ruby, vous devez écrire ce qui suit:
values.select {|v| v > 15}.map {|v| v * v}
Le code Ruby n'est pas aussi compact. Il n'est pas non plus aussi efficace car il convertit d'abord le tableau de valeurs en un tableau intermédiaire plus court contenant les valeurs supérieures à 15. Ensuite, il prend le tableau intermédiaire et génère un tableau final contenant les carrés des intermédiaires. Le tableau intermédiaire est ensuite jeté. Ainsi, Ruby se retrouve avec 3 tableaux en mémoire pendant le calcul; Python n'a besoin que de la liste d'entrée et de la liste résultante.
Python fournit également des compréhensions de carte similaires.
Python prend en charge les tuples; Ruby ne le fait pas. Dans Ruby, vous devez utiliser des tableaux pour simuler des tuples.
Ruby prend en charge les instructions switch / case; Python ne le fait pas.
Ruby prend en charge l' expr ? val1 : val2
opérateur ternaire standard ; Python ne le fait pas.
Ruby ne prend en charge qu'un seul héritage. Si vous avez besoin d'imiter l'héritage multiple, vous pouvez définir des modules et utiliser des mix-ins pour extraire les méthodes de module en classes. Python prend en charge l'héritage multiple plutôt que les mix-ins de modules.
Python prend en charge uniquement les fonctions lambda sur une seule ligne. Les blocs Ruby, qui sont une sorte de / sorte de fonctions lambda, peuvent être arbitrairement grands. Pour cette raison, le code Ruby est généralement écrit dans un style plus fonctionnel que le code Python. Par exemple, pour parcourir une liste dans Ruby, vous faites généralement
collection.each do |value|
...
end
Le bloc fonctionne très bien comme une fonction transmise collection.each
. Si vous deviez faire la même chose en Python, vous devrez définir une fonction interne nommée, puis la transmettre à la collection chaque méthode (si la liste prend en charge cette méthode):
def some_operation(value):
...
collection.each(some_operation)
Cela ne va pas très bien. Ainsi, l'approche non fonctionnelle suivante serait généralement utilisée en Python:
for value in collection:
...
Utiliser les ressources de manière sûre est assez différent entre les deux langues. Ici, le problème est que vous souhaitez allouer une ressource (ouvrir un fichier, obtenir un curseur de base de données, etc.), effectuer une opération arbitraire dessus, puis la fermer de manière sûre même si une exception se produit.
Dans Ruby, étant donné que les blocs sont si faciles à utiliser (voir # 9), vous coderiez généralement ce modèle comme une méthode qui prend un bloc pour l'opération arbitraire à effectuer sur la ressource.
En Python, passer une fonction pour l'action arbitraire est un peu plus maladroit puisque vous devez écrire une fonction interne nommée (voir # 9). Au lieu de cela, Python utilise une with
instruction pour une gestion sûre des ressources. Consultez Comment nettoyer correctement un objet Python? pour plus de détails.