jruby / jruby

chociaż najlepiej MRI i JRuby zachowywałyby się w 100% tak samo we wszystkich sytuacjach, istnieją pewne niewielkie różnice. Niektóre różnice są spowodowane błędami, a te nie są zgłaszane tutaj. Ta strona jest dla różnic, które nie są błędami.

różnice w śledzeniu stosu

ponieważ JRuby jest językiem opartym na JVM, możesz zobaczyć pewne różnice w sposobie renderowania śladów stosu Ruby („backtraces”). Częściowa lista takich przypadków znajduje się poniżej:

  • „nowa” ramka z budowy obiektu może nie być obecna z powodu optymalizacji.
  • core class methods implemented in Java will show a .plik java i numer linii, gdzie CRuby po prostu pokazuje wywołanie .linia RB dwa razy. Nie powinno to mieć wpływu na wyjście caller i caller_locations.
  • może być więcej lub mniej klatek ze względu na sposób rekonstruowania śladu stosu ze stosu JVM.
  • zagnieżdżone bloki nie będą pokazywać poziomu zagnieżdżenia.
  • Ramki najwyższego poziomu mogą pokazywać różne nazwy, w których CRuby pokazuje „”.

ogólnie rzecz biorąc, kod nie powinien polegać na śladach WYJĄTKÓW dokładnie pasujących do CRuby ’ ego, ale gdy istnieje wątpliwa różnica, otwórz błąd. Staramy się dopasować CRuby jak najbliżej.

natywne rozszerzenia C

JRuby nie może uruchamiać natywnych rozszerzeń C. Popularne biblioteki zostały na ogół przeniesione do natywnych rozszerzeń Java. Ponadto, teraz, gdy FFI stał się popularną alternatywą dla bindowania do bibliotek C, używanie go eliminuje potrzebę pisania dużej części natywnych rozszerzeń.

kontynuacje i włókna

JRuby nie obsługuje kontynuacji (Jądra.callcc).

włókna (forma rozdzielonej kontynuacji) są obsługiwane na JRuby, ale każde włókno jest wspierane przez natywny wątek. Może to prowadzić do problemów z zasobami podczas próby użycia większej liczby włókien niż system pozwala na wątki w danym procesie.

wywoływanie zewnętrznych procesów

w systemie Microsoft Windows JRuby jest nieco mądrzejszy podczas uruchamiania zewnętrznych procesów. Jeśli plik wykonywalny nie jest binarnym plikiem wykonywalnym (.exe), MRI wymaga podania sufiksu pliku, ale JRuby radzi sobie bez niego.

na przykład, powiedzmy, że masz plik foo.bat na ścieżce i chcesz go uruchomić.

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

Fork nie jest zaimplementowany

JRuby nie implementuje fork() na żadnej platformie, w tym na tych, gdzie fork() jest dostępny w MRI. Wynika to z faktu, że większości JVM nie można bezpiecznie rozwidlić.

natywny Endian to Big Endian

ponieważ JVM prezentuje kompatybilny procesor JRuby, natywną endiannością JRuby jest Big Endian. Ma to znaczenie dla operacji, które zależą od tego zachowania, takich jak String#unpack i Array#pack dla formatów takich jak I, i, S, i s

dokładność czasu

ponieważ nie jest możliwe uzyskanie precyzji usec W JVM, Time.now.usec nie może zwracać wartości z dokładnością nanosekundową. Nie ma to już miejsca na platformie POSIX (od wersji JRuby 9.1).

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

w systemie Windows natywne wywołanie systemowe nie jest zaimplementowane, a zatem istnieje awaryjny mechanizm precyzji milisekund JVM.Pamiętaj o tym, licząc na precyzję usec w kodzie.

> Time.now.usec=> 582000

priorytet wątku

uwaga: co najmniej od JRuby 1.7.6, priorytety wątku Ruby są mapowane do priorytetów wątku Java, więc ta sekcja nie jest dokładna-możesz użyć tego samego priorytetu dla MRI i JRuby.

w MRI priorytet wątku można ustawić na dowolną wartość w Fixnum (jeśli włączone są wątki natywne) lub -3..3 (Jeśli nie). Wartością domyślną jest 0.

w JRuby wątki są wspierane przez wątki Javy, a ich priorytet wynosi od 1 do 10, domyślnie 5. Jeśli przekażesz wartość spoza tego zakresu do Thread#priority=, priorytet zostanie ustawiony na 1 lub 10.

Uwaga: JVM może ignorować priorytety, to naprawdę zależy od docelowego systemu operacyjnego i z (starszą) Javą musisz przekazać dodatkowe -XX:UseThreadPriorities, aby mogły być używane.

SystemStackError

JRuby nie jest w stanie uratować z SystemStackError. Jeśli twój kod polega na tym, powinieneś raczej spróbować złapać Java::JavaLang::StackOverflowError. Zobacz ten bilet, aby uzyskać więcej informacji.

Argumentless 'proc’

Jeśli podasz proc bez argumentów, a metoda zostanie przekazana blokowi, wtedy Ruby przechwyci przekazany blok. Niektórzy ludzie odkrywają to i prowadzi to do rzadkiego wzorca proc.call. Nie popieramy tego zachowania. Problem polega na tym, że proc jako funkcja jest stosunkowo powszechna, ale zmusza nas do deoptymizacji wszystkich zastosowań proc, takich jak proc { #some code }. Zalecanym obejściem jest zadeklarowanie bloku jawnie za pomocą ampersand def foo(&my_proc).... Jeśli chcesz zachować analogowe zachowanie proc, zezwalamy również na Proc.new, które będzie działać dokładnie tak samo, jak wywołanie gołego proc.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.