que Ruby tem que Python não tem e vice-versa?

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

Existem muitas discussões sobre Python vs Ruby, e todas as considero completamente inúteis, porque todas elas explicam por que o recurso X é péssimo na linguagem Y, ou que afirmam que a linguagem Y não tem X, embora na verdade seja também sei exatamente por que prefiro Python, mas isso também é subjetivo e não ajudaria ninguém a escolher, pois eles podem não ter os mesmos gostos em desenvolvimento que eu.

Seria, portanto, seria interessante listar as diferenças, objetivamente, então não há lambdas de "Python"s. Em vez disso, explique o que os lambdas do Ruby podem fazer que os do Python não podem. Sem subjetividade. O código de exemplo é bom!

Não tenha várias diferenças em uma resposta, por favor. E vote nas que você sabe que estão corretas e nas que você sabe que estão incorretas (ou são subjetivas). Além disso, as diferenças na sintaxe não são interessantes. Sabemos que Python faz com recuo o que Ruby faz com colchetes e extremidades, e que @ é chamado de self em Python.

ATUALIZAÇÃO: Este é agora um wiki da comunidade, então podemos adicionar as grandes diferenças aqui.

p>

Ruby tem uma referência de classe no corpo da classe

No Ruby você tem uma referência à classe (self) já no corpo da classe. Em Python você não tem uma referência à classe até que a construção da classe seja concluída.

Um exemplo:

class Kaka puts self end 

self neste caso é a classe, e este código imprimiria "Kaka". Não há como imprimir o nome da classe ou de outras formas acessar a classe a partir do corpo de definição de classe em Python (fora definições de métodos).

Todas as classes são mutáveis em Ruby

Isso permite que você desenvolva extensões para classes principais. Aqui está um exemplo de uma extensão Rails:

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

Python (imagine que não havia "". beginwith método):

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

Você poderia usá-lo em qualquer sequência (não apenas strings). Para usá-lo você deve importá-lo explicitamente por exemplo, de some_module import starts_with.

O Ruby tem recursos de script semelhantes ao Perl

O Ruby tem regexps de primeira classe, $-variables, o loop de entrada awk/perl linha por linha e outros recursos que o tornam mais adequado para escrever pequenos scripts de shell que alteram arquivos de texto ou atuam como código de cola para outros programas.

Ruby tem continuações de primeira classe

Graças ao comando callcc. Em Python você pode criar continuações por várias técnicas, mas não há suporte embutido na linguagem.

Ruby tem blocos

Com a instrução "do" você pode criar um multi- line função anônima em Ruby, que será passada como um argumento para o método na frente de do, e chamada a partir daí. Em Python, você faria isso passando um método ou com geradores.

Ruby:

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

Python (blocos Ruby correspondem a diferentes construções em Python):

com amethod() as aqui: # `amethod() é um gerenciador de contexto many=lines+of+code goes(here) 

Ou

for here in amethod() : # `amethod()` é um iterável many=lines+of+code goes(aqui) 

Ou

def function(aqui): many =lines+of+code goes(aqui) amethod(function) # `function` é um callback 

Curiosamente, a instrução de conveniência em Ruby para chamar um bloco é chamada de "yield", que em Python criará um gerador.

Ruby:

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

Python:

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

Embora os princípios sejam diferentes, o resultado é surpreendentemente semelhante.

O Ruby suporta programação de estilo funcional (tipo pipe) mais facilmente

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

Python:

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

Python tem geradores embutidos (que são usados como blocos Ruby, como observado acima)

Python tem suporte para geradores na linguagem. No Ruby 1.8 você pode usar o módulo generator que usa continuações para criar um gerador a partir de um bloco. Ou você pode simplesmente usar um block/proc/lambda! Além disso, no Ruby 1.9, as fibras são e podem ser usadas como geradores, e a classe Enumerator é um gerador embutido 4

docs.python. org tem este exemplo de gerador:

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

Compare isso com os exemplos de blocos acima.

Python tem manipulação de espaço de nomes flexível

Em Ruby, quando você importa um arquivo com require, todas as coisas definidas nesse arquivo terminarão em seu namespace global. Isso causa poluição do namespace. A solução para isso são os módulos Rubys. Mas se você criar um namespace com um módulo, precisará usar esse namespace para acessar as classes contidas.

Em Python, o arquivo é um módulo e você pode importar seus nomes contidos com from themodule import *, poluindo assim o namespace se você quiser. Mas você também pode importar apenas nomes selecionados com do módulo importar um nome, outro ou você pode simplesmente importar o módulo e então acessar os nomes com themodule.aname. Se você quiser mais níveis em seu namespace, você pode ter pacotes, que são diretórios com módulos e um arquivo __init__.py.

Python tem docstrings

Docstrings são strings que são anexadas a módulos, funções e métodos e podem ser introspectivas em tempo de execução. Isso ajuda a criar coisas como o comando de ajuda e documentação automática.

def frobnicate(bar): """frobnicate pega uma barra e frobnica-a >>> bar = Bar( ) >>> bar.is_frobnicated() Falso >>> frobnicate(bar) >>> bar.is_frobnicated() Verdadeiro """ 

Ruby "s equivalentes são semelhantes a javadocs e localizados acima do método em vez de dentro dele. Eles podem ser recuperados em tempo de execução dos arquivos usando 1.9"s Method#source_location exemplo de uso

Python tem herança múltipla

Ruby não ("de propósito" -- veja Ruby, veja aqui como "é feito em Ruby). Ele reutiliza o conceito do módulo como um tipo de classe abstrata.

Python tem compreensão de lista/dict

Python:

res = [x* x para x em range(1, 10)] 

Ruby:

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

Python:

>>> (x*x para x no intervalo(10)) <objeto gerador <genexpr> em 0xb7c1ccd4> >>> list(_) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 

Rubi:

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

Python 2.7+:

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

Rubi:

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

Python tem decoradores

Coisas semelhantes a decoradores também podem ser criadas em Ruby, e também pode-se argumentar que eles não são tão necessários quanto em Python.

Diferenças de sintaxe

Ruby requer "end" ou "}" para fechar todos os seus escopos, enquanto Python usa apenas espaço em branco. Houve tentativas recentes em Ruby de permitir recuo apenas de espaço em branco http://github.com /michaeledgar/sem costura