Ruby tem blocos; Python não.
Python tem funções; Ruby não. No Python, você pode pegar qualquer função ou método e passá-lo para outra função. No Ruby, tudo é um método, e os métodos não podem ser passados diretamente. Em vez disso, você precisa envolvê-los nos Proc para passá-los.
Ruby e Python suportam fechamentos, mas de maneiras diferentes. No Python, você pode definir uma função dentro de outra função. A função interna possui acesso de leitura a variáveis da função externa, mas não acesso de gravação. No Ruby, você define fechamentos usando blocos. Os fechamentos têm acesso completo de leitura e gravação a variáveis do escopo externo.
O Python possui compreensões de lista, que são bastante expressivas. Por exemplo, se você tiver uma lista de números, poderá escrever
[x*x for x in values if x > 15]
para obter uma nova lista dos quadrados de todos os valores maiores que 15. No Ruby, você teria que escrever o seguinte:
values.select {|v| v > 15}.map {|v| v * v}
O código Ruby não parece tão compacto. Também não é tão eficiente, pois primeiro converte a matriz de valores em uma matriz intermediária mais curta, contendo valores maiores que 15. Em seguida, ela pega a matriz intermediária e gera uma matriz final contendo os quadrados dos intermediários. A matriz intermediária é então descartada. Então, Ruby acaba com 3 matrizes na memória durante o cálculo; O Python precisa apenas da lista de entrada e da lista resultante.
O Python também fornece compreensões de mapas semelhantes.
Python suporta tuplas; Ruby não. No Ruby, você precisa usar matrizes para simular tuplas.
Ruby suporta instruções switch / case; Python não.
Ruby suporta o expr ? val1 : val2
operador ternário padrão ; Python não.
Ruby suporta apenas herança única. Se você precisar imitar várias heranças, poderá definir módulos e usar mix-ins para colocar os métodos do módulo em classes. O Python suporta herança múltipla em vez de mix-ins de módulo.
O Python suporta apenas funções lambda de linha única. Blocos Ruby, que são um tipo de / tipo de funções lambda, podem ser arbitrariamente grandes. Por esse motivo, o código Ruby geralmente é escrito em um estilo mais funcional que o código Python. Por exemplo, para percorrer uma lista em Ruby, você normalmente faz
collection.each do |value|
...
end
O bloco funciona como uma função que está sendo passada para collection.each
. Se você fizesse a mesma coisa em Python, teria que definir uma função interna nomeada e depois passar para a coleção cada método (se a lista suportasse esse método):
def some_operation(value):
...
collection.each(some_operation)
Isso não flui muito bem. Portanto, normalmente a seguinte abordagem não funcional seria usada no Python:
for value in collection:
...
Usar recursos de maneira segura é bem diferente entre os dois idiomas. Aqui, o problema é que você deseja alocar algum recurso (abrir um arquivo, obter um cursor no banco de dados, etc.), executar alguma operação arbitrária e, em seguida, fechá-lo de maneira segura, mesmo que ocorra uma exceção.
No Ruby, como os blocos são muito fáceis de usar (consulte o item 9), você normalmente codifica esse padrão como um método que leva um bloco para a operação arbitrária executar no recurso.
No Python, passar uma função para a ação arbitrária é um pouco mais complicado, já que você precisa escrever uma função interna nomeada (consulte # 9). Em vez disso, o Python usa uma with
instrução para manipulação segura de recursos. Consulte Como faço para limpar corretamente um objeto Python? para mais detalhes.