Aunque idealmente MRI y JRuby se comportarían 100% igual en todas las situaciones, hay algunas diferencias menores. Algunas diferencias se deben a errores, y no se reportan aquí. Esta página es para diferencias que no son errores.
Diferencias de seguimiento de pila
Debido a que JRuby es un lenguaje basado en JVM, es posible que vea algunas diferencias en la forma en que se renderizan las trazas de pila de Ruby («backtraces»). A continuación figura una lista parcial de esos casos:
- El marco «nuevo» de la construcción de un objeto puede no estar presente debido a optimizaciones.
- Los métodos de clase principales implementados en Java mostrarán a .archivo java y número de línea donde CRuby solo mostraría la llamada .línea rb dos veces. Esto no debería afectar a la salida
caller
ycaller_locations
. - Puede haber más o menos fotogramas debido a cómo reconstruimos una traza de pila a partir de la pila de JVM.
- Los bloques anidados no mostrarán el nivel de anidamiento.
- Los fotogramas de nivel superior pueden mostrar nombres diferentes donde CRuby muestra»».
En general, el código no debe basarse en retrotracciones de excepción que coincidan exactamente con CRuby, pero cuando haya una diferencia cuestionable, abra un error. Tratamos de emparejar a CRuby lo más cerca posible.
Extensiones nativas de C
JRuby no puede ejecutar extensiones nativas de C. Las bibliotecas populares generalmente se han portado a Extensiones nativas de Java. Además, ahora que FFI se ha convertido en una alternativa popular al enlace a bibliotecas C, usarlo evita la necesidad de escribir una gran parte de extensiones nativas.
Continuaciones y fibras
JRuby no admite continuaciones (Núcleo.callcc).
Las fibras (una forma de continuación delimitada) se soportan en JRuby, pero cada fibra está respaldada por un hilo nativo. Esto puede generar problemas de recursos al intentar usar más fibras de las que el sistema permite en un proceso determinado.
Invocar procesos externos
En Microsoft Windows, JRuby es un poco más inteligente al iniciar procesos externos. Si el archivo ejecutable no es un ejecutable binario (.exe
), MRI también requiere que proporcione el sufijo de archivo, pero JRuby lo gestiona sin él.
Por ejemplo, supongamos que tiene un archivo foo.bat
en su RUTA de acceso y desea ejecutarlo.
system( 'foo' ) # works on JRuby, fails on MRIsystem( 'foo.bat' ) # works both in JRuby and MRI
Fork no está implementado
JRuby no implementa fork()
en ninguna plataforma, incluidas aquellas en las que fork()
está disponible en MRI. Esto se debe al hecho de que la mayoría de las JVM no se pueden bifurcar de forma segura.
Endian nativo es Big Endian
Dado que la JVM presenta una CPU compatible con JRuby, la endianidad nativa de JRuby es Big Endian. Esto es importante para operaciones que dependen de ese comportamiento, como String#unpack
y Array#pack
para formatos como I
, i
, S
, y s
.
Precisión de tiempo
Dado que no es posible obtener usec
precisión bajo una JVM, Time.now.usec
no puede devolver valores con precisión de nanosegundos. Este ya no es el caso bajo una plataforma POSIX (desde JRuby 9.1).
irb(main):004:0> Time.now.usec=> 815414
En Windows no se implementa una llamada al sistema nativa y, por lo tanto, existe el respaldo de precisión de milisegundos de JVM.Tenga esto en cuenta cuando cuente con usec
de precisión en su código.
> Time.now.usec=> 582000
Prioridad de subprocesos
NOTA: al menos desde JRuby 1.7.6, las prioridades de subprocesos de Ruby se asignan a las prioridades de subprocesos de Java, por lo que esta sección no es precisa: puede usar la misma prioridad para MRI y JRuby.
En MRI, la prioridad de subprocesos se puede establecer en cualquier valor en Fixnum (si los subprocesos nativos están habilitados) o -3..3 (si no). El valor predeterminado es 0.
En JRuby, los subprocesos están respaldados por subprocesos Java, y la prioridad varía de 1 a 10, con un valor predeterminado de 5. Si pasa un valor fuera de este rango a Thread#priority=
, la prioridad se establecerá en 1 o 10.
NOTA: que la JVM puede ignorar las prioridades, realmente depende del sistema operativo de destino y con Java (anterior) necesita pasar el -XX:UseThreadPriorities
extra para que se usen.
SystemStackError
JRuby no puede rescatar desde SystemStackError
. Si su código se basa en esto, debería intentar capturar un Java::JavaLang::StackOverflowError
. Consulte este ticket para obtener más información.
‘proc’sin argumentos
Si suministra proc
sin argumentos y el método pasa un bloque, Ruby terminará capturando el bloque in pasado. Algunas personas descubren esto y conduce a un patrón raro de proc.call
. No apoyamos este comportamiento. El problema es proc, ya que una función es relativamente común, pero nos obliga a desoptimizar todos los usos de proc como proc { #some code }
. La solución recomendada es declarar el bloque explícitamente usando un ampersand def foo(&my_proc)...
. Si desea que el comportamiento analógico sea proc, también permitimos Proc.new
, que funcionará exactamente igual que una llamada de proc desnuda.