jruby / jruby

i když by se v ideálním případě MRI a JRuby chovali 100% stejně ve všech situacích, existují určité drobné rozdíly. Některé rozdíly jsou způsobeny chybami, a ty zde nejsou hlášeny. Tato stránka je určena pro rozdíly, které nejsou chyby.

Stack trace Differences

protože JRuby je jazyk založený na JVM, můžete vidět některé rozdíly v tom, jak Ruby stack traces („backtraces“) jsou vykresleny. Částečný seznam takových případů je níže:

  • „nový“ rámec z konstrukce objektu nemusí být přítomen kvůli optimalizacím.
  • metody základní třídy implementované v Javě zobrazí a .java soubor a číslo řádku, kde by CRuby jen ukázat volání .RB linka dvakrát. To by nemělo ovlivnit výstup caller a caller_locations.
  • může být více nebo méně snímků kvůli tomu, jak rekonstruujeme stopu zásobníku ze zásobníku JVM.
  • vnořené bloky nezobrazí úroveň vnoření.
  • snímky nejvyšší úrovně mohou zobrazovat různé názvy, kde CRuby zobrazuje““.

obecně by se kód neměl spoléhat na výjimky, které přesně odpovídají Crubymu, ale pokud existuje sporný rozdíl, otevřete chybu. Snažíme se s Crubym vyrovnat co nejtěsněji.

Native C Extensions

JRuby nelze spustit native C extensions. Populární knihovny byly obecně přeneseny do nativních rozšíření Java. Nyní, když se FFI stala populární alternativou k vazbě na knihovny C, jeho použití eliminuje potřebu psát velký kus nativních rozšíření.

pokračování a vlákna

JRuby nepodporuje pokračování (jádro.callcc).

vlákna (forma odděleného pokračování) jsou podporována na JRuby, ale každé vlákno je podporováno nativním vláknem. To může vést k problémům se zdroji při pokusu o použití více vláken, než systém umožňuje vlákna v daném procesu.

vyvolání externích procesů

v systému Microsoft Windows je JRuby při spouštění externích procesů o něco chytřejší. Pokud spustitelný soubor není binární spustitelný soubor (.exe), MRI vyžaduje, abyste dali příponu souboru, ale JRuby spravuje bez něj.

například řekněte, že máte na své cestě soubor foo.bat a chcete jej spustit.

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

vidlice není implementována

JRuby neimplementuje fork() na žádné platformě, včetně těch, kde je fork() k dispozici v MRI. To je způsobeno skutečností, že většinu JVM nelze bezpečně rozvětvit.

nativní Endian je Big Endian

vzhledem k tomu, že JVM představuje kompatibilní CPU pro JRuby, nativní endiannost JRuby je Big Endian. To záleží na operacích, které závisí na tomto chování, jako String#unpack a Array#pack pro formáty jako I, i, S, a s.

časová přesnost

protože není možné získat usec přesnost pod JVM, Time.now.usec nemůže vrátit hodnoty s nanosekundovou přesností. To již není případ platformy POSIX (od JRuby 9.1).

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

v systému Windows není implementováno nativní systémové volání, a proto je zde JVM milisekundová přesnost.Mějte to na paměti při počítání s přesností usec ve vašem kódu.

> Time.now.usec=> 582000

Priorita závitu

poznámka: přinejmenším již od JRuby 1.7.6 jsou priority vláken Ruby mapovány na priority vláken Java, takže tato část není přesná-stejnou prioritu můžete použít pro MRI a JRuby.

v MRI lze prioritu vlákna nastavit na libovolnou hodnotu v Fixnum (pokud jsou povolena nativní vlákna) nebo -3..3 (pokud ne). Výchozí hodnota je 0.

v JRuby jsou vlákna podporována vlákny Java a priorita se pohybuje od 1 do 10, s výchozím nastavením 5. Pokud předáte hodnotu mimo tento rozsah na Thread#priority=, priorita bude nastavena na 1 nebo 10.

poznámka: že JVM může ignorovat priority, opravdu záleží na cílovém operačním systému a se (starší) Javou musíte předat další -XX:UseThreadPriorities, aby mohly být použity.

SystemStackError

JRuby není schopen zachránit z SystemStackError. Pokud se na to váš kód spoléhá, měli byste se raději pokusit chytit Java::JavaLang::StackOverflowError. Další informace naleznete v této vstupence.

bez argumentů „proc“

pokud zadáte proc bez argumentů a metoda se stane, že byla předána blokem, Ruby nakonec zachytí předaný blok. Někteří lidé to objevují a vede to ke vzácnému vzoru proc.call. Toto chování nepodporujeme. Problém je proc, protože funkce je relativně běžná, ale nutí nás deoptimalizovat všechna použití proc jako proc { #some code }. Doporučená práce kolem je deklarovat blok explicitně pomocí ampersand def foo(&my_proc).... Pokud chcete analogové chování proc, povolíme také Proc.new, které bude fungovat přesně stejně jako holé volání proc.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.