embora idealmente MRI e JRuby se comportassem 100% o mesmo em todas as situações, existem algumas pequenas diferenças. Algumas diferenças são devidas a bugs, e essas não são relatadas aqui. Esta página é para diferenças que não são bugs.
Stack Trace Differences
porque JRuby é uma linguagem baseada em JVM, você pode ver algumas diferenças em como os traços de pilha Ruby (“backtraces”) são renderizados. Uma lista parcial desses casos está abaixo:
- o quadro” novo ” da construção de um objeto pode não estar presente devido a otimizações.
- os métodos de classe Central implementados em Java mostrarão um .arquivo java e número de linha onde CRuby mostraria apenas a chamada .linha rb duas vezes. Isso não deve afetar a saída
caller
ecaller_locations
. - pode haver mais ou menos quadros devido à forma como reconstruímos um rastreamento de pilha da pilha JVM.
- os blocos aninhados não mostrarão o nível de aninhamento.
- quadros de Nível Superior podem mostrar nomes diferentes onde CRuby mostra””.
em geral, o código não deve depender de backtraces de exceção correspondentes a CRuby exatamente, mas quando houver uma diferença questionável, abra um bug. Tentamos combinar CRuby o mais próximo possível.
extensões C nativas
JRuby não pode executar extensões c nativas. Bibliotecas populares geralmente foram portadas para extensões nativas Java. Além disso, agora que o FFI se tornou uma alternativa popular à ligação às bibliotecas C, usá-lo evita a necessidade de escrever um grande pedaço de extensões nativas.
Continuações e Fibras
JRuby não suporta continuações (Kernel.callcc).
fibras (uma forma de continuação delimitada) são suportadas em JRuby, mas cada fibra é apoiada por um fio nativo. Isso pode levar a problemas de recursos ao tentar usar mais fibras do que o sistema permite threads em um determinado processo.
invocando processos externos
no Microsoft Windows, o JRuby é um pouco mais inteligente ao iniciar processos externos. Se o arquivo executável não é um executável binário (.exe
), MRI requer que você dê o sufixo do arquivo também, mas JRuby gerencia sem ele.
por exemplo, digamos que você tenha o arquivo foo.bat
em seu caminho e queira executá-lo.
system( 'foo' ) # works on JRuby, fails on MRIsystem( 'foo.bat' ) # works both in JRuby and MRI
o garfo não está implementado
o JRuby não implementa fork()
em nenhuma plataforma, incluindo aquelas em que fork()
está disponível na ressonância magnética. Isso se deve ao fato de que a maioria das JVMs não pode ser bifurcada com segurança.
Endian nativo é Big Endian
como a JVM apresenta uma CPU compatível com JRuby, a endianidade nativa de JRuby é Big Endian. Isso não importa para operações que dependem desse comportamento, como String#unpack
e Array#pack
para formatos como I
, i
, S
, e s
.
precisão de tempo
uma vez que não é possível obter usec
precisão sob uma JVM, Time.now.usec
não pode retornar valores com precisão de nanossegundos. Este não é mais o caso em uma plataforma POSIX (desde JRuby 9.1).
irb(main):004:0> Time.now.usec=> 815414
no Windows, uma chamada de Sistema nativa não é implementada e, portanto, há o fallback de precisão de milissegundos JVM.Tenha isso em mente ao contar com precisão usec
em seu código.
> Time.now.usec=> 582000
prioridade de Thread
nota: pelo menos desde JRuby 1.7.6, as prioridades de thread Ruby são mapeadas para as prioridades de thread Java, portanto, esta seção não é precisa-você pode usar a mesma prioridade para MRI e JRuby.
no MRI, a prioridade de Thread pode ser definida como qualquer valor no Fixnum (se os threads nativos estiverem ativados) ou -3..3 (Se não). O valor padrão é 0.
em JRuby, os Threads são apoiados por threads Java e a prioridade varia de 1 a 10, com um padrão de 5. Se você passar um valor fora desse intervalo para Thread#priority=
, a prioridade será definida como 1 ou 10.
nota: que a JVM pode ignorar prioridades, realmente depende do sistema operacional de destino e com Java (mais antigo) você precisa passar o extra -XX:UseThreadPriorities
para que eles sejam usados.
SystemStackError
JRuby não é capaz de resgatar de SystemStackError
. Se o seu código confiar nisso, você deve tentar pegar um Java::JavaLang::StackOverflowError
. Veja este bilhete para mais informações.
Argumentless ‘proc’
se você fornecer proc
sem argumentos e o método tiver sido passado um bloco, o Ruby acabará capturando o bloco passado. Algumas pessoas descobrem isso e isso leva a um padrão raro de proc.call
. Não apoiamos esse comportamento. O problema é proc como uma função é relativamente comum, mas nos força a deoptimize todos os usos de proc como proc { #some code }
. A solução recomendada é declarar o bloco explicitamente usando um ampersand def foo(&my_proc)...
. Se você deseja que o comportamento analógico proc, também permitimos Proc.new
que funcionará exatamente da mesma forma que uma chamada proc nua.