hoewel MRI en JRuby zich idealiter in alle situaties 100% hetzelfde gedragen, zijn er enkele kleine verschillen. Sommige verschillen zijn te wijten aan bugs, en die worden hier niet gerapporteerd. Deze pagina is voor verschillen die geen bugs zijn.
Stack Trace verschillen
omdat JRuby een op JVM gebaseerde taal is, kunt u enkele verschillen zien in hoe Ruby stack traces (“backtraces”) worden weergegeven. Hieronder volgt een gedeeltelijke lijst van dergelijke gevallen:
- het” nieuwe ” frame van het construeren van een object is mogelijk niet aanwezig vanwege optimalisaties.
- Core class methoden geà mplementeerd in Java zullen een tonen .java-bestand en regelnummer waar CRuby alleen de oproep zou tonen .rb lijn twee keer. Dit zou geen invloed moeten hebben op de uitvoer van
caller
encaller_locations
. - er kunnen meer of minder frames zijn vanwege hoe we een stack trace reconstrueren van de JVM stack.
- geneste blokken zullen het niveau van nesting niet tonen.
- top-level frames kunnen een andere naam tonen waarbij CRuby “” toont.
in het algemeen moet code niet vertrouwen op Exception backtraces die exact overeenkomen met CRuby, maar als er een twijfelachtig verschil is, open dan een bug. We proberen CRuby zo dicht mogelijk te benaderen.
Native C-extensies
JRuby kan native C-extensies niet uitvoeren. Populaire bibliotheken zijn over het algemeen overgezet naar Java Native extensies. Ook, nu dat FFI is uitgegroeid tot een populair alternatief voor binding aan C bibliotheken, het gebruik van het overbodig maakt om een groot deel van de inheemse extensies te schrijven.
Continuaties en vezels
JRuby ondersteunt geen continuaties (Kernel.callcc).
vezels (een vorm van gescheiden voortzetting) worden ondersteund op JRuby, maar elke vezel wordt ondersteund door een native thread. Dit kan leiden tot resource problemen bij het proberen om meer vezels te gebruiken dan het systeem threads toestaat in een bepaald proces.
externe processen
op Microsoft Windows is JRuby een beetje slimmer bij het opstarten van externe processen. Als het uitvoerbare bestand geen binair uitvoerbare bestand is (.exe
), vereist MRI dat u ook het achtervoegsel van het bestand opgeeft, maar JRuby beheert het zonder het.
bijvoorbeeld, stel dat je bestand foo.bat
op je pad hebt en het wilt uitvoeren.
system( 'foo' ) # works on JRuby, fails on MRIsystem( 'foo.bat' ) # works both in JRuby and MRI
Fork is Niet geïmplementeerd
JRuby implementeert fork()
niet op enig platform, inclusief die waar fork()
beschikbaar is in MRI. Dit komt door het feit dat de meeste JVM ‘ s niet veilig kunnen worden gevorkt.
Native Endian is Big endian
omdat JVM een compatibele CPU aan JRuby presenteert, is de native Endianess van JRuby Big Endian. Dit doet er wel toe voor bewerkingen die afhankelijk zijn van dat gedrag, zoals String#unpack
en Array#pack
voor formaten zoals I
, i
, S
, en s
.
Tijdprecisie
omdat het niet mogelijk is om onder een JVM een precisie van usec
te verkrijgen, kan Time.now.usec
geen waarden retourneren met nanosecondeprecisie. Dit is niet langer het geval onder een POSIX-platform (sinds JRuby 9.1).
irb(main):004:0> Time.now.usec=> 815414
op Windows is een native systeemaanroep niet geà mplementeerd en dus is er de JVM milliseconde precision fallback.Houd dit in gedachten wanneer u rekent op usec
precisie in uw code.
> Time.now.usec=> 582000
Threadprioriteit
opmerking: vanaf ten minste JRuby 1.7.6 worden Ruby threadprioriteiten toegewezen aan Java threadprioriteiten, dus deze sectie is niet accuraat — U kunt dezelfde prioriteit gebruiken voor MRI en JRuby.
bij MRI kan de Threadprioriteit worden ingesteld op elke waarde in Fixnum (als native threads zijn ingeschakeld) of -3..3 (zo niet). De standaardwaarde is 0.
in JRuby worden Threads ondersteund door Java threads, en de prioriteit varieert van 1 tot 10, met een standaardwaarde van 5. Als u een waarde buiten dit bereik geeft aan Thread#priority=
, wordt de prioriteit ingesteld op 1 of 10.
opmerking: dat de JVM prioriteiten zou kunnen negeren, hangt echt af van het doel OS en met (ouder) Java moet je de extra -XX:UseThreadPriorities
doorgeven om ze te gebruiken.
SystemStackError
JRuby is niet in staat om te redden van SystemStackError
. Als uw code hierop vertrouwt, moet u liever proberen een Java::JavaLang::StackOverflowError
te vangen. Zie dit ticket voor meer informatie.
Argumentless ‘proc’
als u proc
opgeeft zonder argumenten en de methode is toevallig een blok gepasseerd, dan zal Ruby uiteindelijk het doorgegeven blok vastleggen. Sommige mensen ontdekken dit en het leidt tot een zeldzaam patroon van proc.call
. Wij steunen dit gedrag niet. Het probleem is dat proc als een functie relatief algemeen is, maar het dwingt ons om alle toepassingen van proc zoals proc { #some code }
te deoptimaliseren. Het aanbevolen werk is om het blok expliciet te declareren met behulp van een ampersand def foo(&my_proc)...
. Als je analoog gedrag naar proc wilt, staan we ook Proc.new
toe, wat precies hetzelfde werkt als een kale proc aanroep.