deși în mod ideal RMN și JRuby s-ar comporta 100% la fel în toate situațiile, există unele diferențe minore. Unele diferențe se datorează bug-urilor, iar acestea nu sunt raportate aici. Această pagină este pentru diferențele care nu sunt bug-uri.
Stack Trace Differences
deoarece JRuby este un limbaj bazat pe JVM, este posibil să vedeți unele diferențe în modul în care sunt redate urmele Ruby stack („backtraces”). O listă parțială a acestor cazuri este mai jos:
- cadrul „Nou” de la construirea unui obiect poate să nu fie prezent din cauza optimizărilor.
- metode de clasă de bază implementate în Java va arăta o .fișier java și numărul de linie în cazul în care CRuby ar arăta doar de asteptare .linia rb de două ori. Acest lucru nu ar trebui să afecteze
caller
șicaller_locations
ieșire. - pot exista mai multe sau mai puține cadre datorită modului în care reconstruim o urmă de stivă din stiva JVM.
- blocurile imbricate nu vor afișa nivelul de cuibărire.
- cadrele de nivel superior pot afișa nume diferite în care CRuby arată „”.
în general, codul nu ar trebui să se bazeze pe backtraces excepție de potrivire CRuby exact, dar atunci când există o diferență discutabilă vă rugăm să deschideți un bug. Încercăm să-l potrivim pe CRuby cât mai aproape posibil.
extensii C Native
JRuby nu poate rula extensii C native. Bibliotecile populare au fost în general portate la extensiile native Java. De asemenea, acum că FFI a devenit o alternativă populară la legarea la bibliotecile C, utilizarea acestuia elimină necesitatea de a scrie o bucată mare de extensii native.
continuări și fibre
JRuby nu acceptă continuări (Kernel.callcc).
fibrele (o formă de continuare delimitată) sunt susținute pe JRuby, dar fiecare fibră este susținută de un fir nativ. Acest lucru poate duce la probleme de resurse atunci când încercați să utilizați mai multe fibre decât sistemul permite fire într-un anumit proces.
invocarea proceselor externe
pe Microsoft Windows, JRuby este puțin mai inteligent atunci când lansează procese externe. Dacă fișierul executabil nu este un executabil binar (.exe
), RMN necesită să dați și sufixul fișierului, dar JRuby gestionează fără el.
de exemplu, spuneți că aveți fișierul foo.bat
pe calea dvs. și doriți să îl rulați.
system( 'foo' ) # works on JRuby, fails on MRIsystem( 'foo.bat' ) # works both in JRuby and MRI
Furca nu este implementată
JRuby nu implementează fork()
pe nicio platformă, inclusiv pe cele în care fork()
este disponibil în RMN. Acest lucru se datorează faptului că majoritatea JVM-urilor nu pot fi bifurcate în siguranță.
Endianul nativ este Big Endian
deoarece JVM prezintă un procesor compatibil cu JRuby, endianitatea nativă a JRuby este Big Endian. Acest lucru contează pentru operațiunile care depind de acel comportament, cum ar fi String#unpack
și Array#pack
pentru formate precum I
, i
, S
, și s
.
precizie de timp
deoarece nu este posibil să se obțină usec
precizie sub un JVM, Time.now.usec
nu poate returna valori cu precizie nanosecundă. Acest lucru nu mai este cazul sub o platformă POSIX (de la JRuby 9.1).
irb(main):004:0> Time.now.usec=> 815414
pe Windows Un apel de sistem nativ nu este implementat și, prin urmare, există JVM milisecunde precizie de rezervă.Rețineți acest lucru atunci când contați pe precizia usec
din codul dvs.
> Time.now.usec=> 582000
Thread priority
notă: de la cel puțin cât mai devreme JRuby 1.7.6, prioritățile Ruby thread sunt mapate la prioritățile java thread, astfel încât această secțiune nu este corectă-puteți utiliza aceeași prioritate pentru RMN și JRuby.
în RMN, prioritatea firului poate fi setată la orice valoare în Fixnum (dacă firele native sunt activate) sau -3..3 (dacă nu). Valoarea implicită este 0.
în JRuby, firele sunt susținute de fire Java, iar prioritatea variază de la 1 la 10, cu o valoare implicită de 5. Dacă treceți o valoare în afara acestui interval la Thread#priority=
, prioritatea va fi setată la 1 sau 10.
notă: că JVM ar putea ignora prioritățile, într-adevăr depinde de sistemul de operare țintă și cu Java (mai vechi) trebuie să treci extra -XX:UseThreadPriorities
pentru ca acestea să fie utilizate.
SystemStackError
JRuby nu este în măsură să salveze de la SystemStackError
. Dacă codul dvs. se bazează pe acest lucru, ar trebui să încercați mai degrabă să prindeți un Java::JavaLang::StackOverflowError
. A se vedea acest bilet pentru informații suplimentare.
Argumentless ‘proc’
dacă furnizați proc
fără argumente și metoda se întâmplă să fi fost trecut un bloc, atunci Ruby va sfârși prin capturarea trecut în bloc. Unii oameni descoperă acest lucru și duce la un model rar de proc.call
. Nu susținem acest comportament. Problema este proc ca o funcție este relativ comună, dar ne obligă să deoptimize toate utilizările proc ca proc { #some code }
. Lucrul recomandat este să declarați blocul în mod explicit folosind un ampersand def foo(&my_proc)...
. Dacă doriți un comportament Analog la proc, permitem, de asemenea, Proc.new
care va funcționa exact la fel ca un apel proc gol.