jruby / jruby

Anche se idealmente MRI e JRuby si comporterebbero al 100% allo stesso modo in tutte le situazioni, ci sono alcune differenze minori. Alcune differenze sono dovute a bug, e quelli non sono riportati qui. Questa pagina è per le differenze che non sono bug.

Stack Trace Differences

Poiché JRuby è un linguaggio basato su JVM, potresti vedere alcune differenze nel modo in cui vengono renderizzate le tracce dello stack Ruby (“backtraces”). Di seguito è riportato un elenco parziale di tali casi:

  • Il “nuovo” frame dalla costruzione di un oggetto potrebbe non essere presente a causa delle ottimizzazioni.
  • Metodi di classe Core implementati in Java mostrerà un .file java e numero di riga in cui CRuby mostrerebbe solo la chiamata .linea rb due volte. Ciò non dovrebbe influire sull’output caller e caller_locations.
  • Potrebbero esserci più o meno frame a causa del modo in cui ricostruiamo una traccia dello stack dallo stack JVM.
  • I blocchi nidificati non mostreranno il livello di nidificazione.
  • I fotogrammi di livello superiore possono mostrare nomi diversi in cui CRuby mostra””.

In generale, il codice non dovrebbe fare affidamento su backtraces di eccezione che corrispondono esattamente a CRuby, ma quando c’è una differenza discutibile, apri un bug. Cerchiamo di abbinare CRuby il più vicino possibile.

Estensioni C native

JRuby non può eseguire estensioni C native. Le librerie popolari sono state generalmente portate su estensioni native Java. Inoltre, ora che FFI è diventata un’alternativa popolare all’associazione alle librerie C, il suo utilizzo evita la necessità di scrivere una grande quantità di estensioni native.

Continuazioni e fibre

JRuby non supporta continuazioni (Kernel.callcc).

Le fibre (una forma di continuazione delimitata) sono supportate su JRuby, ma ogni fibra è supportata da un thread nativo. Ciò può portare a problemi di risorse quando si tenta di utilizzare più fibre di quelle che il sistema consente ai thread in un determinato processo.

Invocare processi esterni

Su Microsoft Windows, JRuby è un po ‘ più intelligente quando si avviano processi esterni. Se il file eseguibile non è un eseguibile binario (.exe), MRI richiede di dare anche il suffisso del file, ma JRuby gestisce senza di esso.

Ad esempio, supponiamo che tu abbia il file foo.bat sul tuo PERCORSO e desideri eseguirlo.

system( 'foo' ) # works on JRuby, fails on MRIsystem( 'foo.bat' ) # works both in JRuby and MRI

Fork non è implementato

JRuby non implementa fork() su nessuna piattaforma, inclusi quelli in cui fork() è disponibile in MRI. Ciò è dovuto al fatto che la maggior parte delle JVM non può essere biforcuta in modo sicuro.

Endian nativo è Big Endian

Poiché la JVM presenta una CPU compatibile con JRuby, la endianità nativa di JRuby è Big Endian. Questo è importante per le operazioni che dipendono da quel comportamento, come String#unpack e Array#pack per formati come I, i, S, e s.

Precisione temporale

Poiché non è possibile ottenere usec precisione in una JVM, Time.now.usec non è possibile restituire valori con precisione nanoseconda. Questo non è più il caso di una piattaforma POSIX (da JRuby 9.1).

irb(main):004:0> Time.now.usec=> 815414

Su Windows una chiamata di sistema nativa non è implementata e quindi c’è il fallback di precisione JVM millisecondo.Tienilo a mente quando conti sulla precisione usec nel tuo codice.

> Time.now.usec=> 582000

Priorità thread

NOTA: almeno a partire da JRuby 1.7.6, le priorità dei thread Ruby sono mappate alle priorità dei thread Java, quindi questa sezione non è accurata: è possibile utilizzare la stessa priorità per MRI e JRuby.

In MRI, la priorità del thread può essere impostata su qualsiasi valore in Fixnum (se i thread nativi sono abilitati) o -3..3 (se non). Il valore predefinito è 0.

In JRuby, i thread sono supportati da thread Java e la priorità varia da 1 a 10, con un valore predefinito di 5. Se si passa un valore al di fuori di questo intervallo a Thread#priority=, la priorità verrà impostata su 1 o 10.

NOTA: che la JVM potrebbe ignorare le priorità, dipende davvero dal sistema operativo di destinazione e con Java (più vecchio) è necessario passare l’extra -XX:UseThreadPriorities per utilizzarli.

SystemStackError

JRuby non è in grado di salvare da SystemStackError. Se il tuo codice si basa su questo, dovresti piuttosto provare a catturare un Java::JavaLang::StackOverflowError. Vedi questo biglietto per ulteriori informazioni.

‘proc’Argumentless

Se si fornisce proc senza argomenti e il metodo viene passato a un blocco, Ruby finirà per catturare il blocco passato. Alcune persone scoprono questo e porta a un modello raro di proc.call. Non sosteniamo questo comportamento. Il problema è che proc come funzione è relativamente comune ma ci costringe a deottimizzare tutti gli usi di proc come proc { #some code }. Il lavoro consigliato è dichiarare esplicitamente il blocco usando una e commerciale def foo(&my_proc).... Se si desidera un comportamento analogico a proc, si consente anche Proc.new che funzionerà esattamente come una chiamata bare proc.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.