Jaka jest różnica między ~> i> = podczas określania rubygem w Gemfile?

120

Często widzę następującą notację (~>) w Gemfile.

gem "cucumber", "~>0.8.5"
gem "rspec", "~>1.3.0"

Wiem, że znak (> =) jest po prostu większy lub równy, ale co oznacza notacja (~>)? Czy oba są takie same, czy ma jakąś istotną różnicę?

Samouk
źródło
6
Zobacz także: Znaczenie ~>w wymogu wersji .
Jörg W Mittag
28
~>jest czasami nazywany „operatorem nasienia”.
Andrew Grimm
3
Czy możesz określić zakres wersji Rubiego w swoim pliku Gemfile? Np.ruby "~>2.0"
Dennis
1
lub nazywany twiddle-wakka
SuckerForMayhem
@Dennis tutaj jest odpowiedź na twoje pytanie: stackoverflow.com/a/23116552/6359753
Henry Yang

Odpowiedzi:

165

To pesymistyczne ograniczenie wersji . RubyGems zwiększy ostatnią cyfrę w dostarczonej wersji i będzie jej używać, aż osiągnie wersję maksymalną. Więc ~>0.8.5jest semantycznie równoważne z:

gem "cucumber", ">=0.8.5", "<0.9.0"

Najłatwiej o tym pomyśleć jest to, że nie przeszkadza ci zwiększenie ostatniej cyfry do dowolnej dowolnej wartości, ale liczba poprzedzająca ją w ciągu nie może być większa niż ta, którą podałeś. Tak więc dla ~>0.8.5trzeciej cyfry (5) dopuszczalna jest dowolna wartość, pod warunkiem że jest większa lub równa 5, ale początkowe 0,8 musi wynosić „0,8”.

Możesz to zrobić na przykład, jeśli myślisz, że wersja 0.9 wprowadzi pewne istotne zmiany, ale wiesz, że cała seria wydań 0.8.x to tylko poprawki błędów.

Jednak proste użycie ">=0.8.5"wskazywałoby, że każda wersja późniejsza niż (lub równa) 0.8.5 jest akceptowalna. Nie ma górnej granicy.

eldarerathis
źródło
Jak to się zachowuje w przypadku klejnotów, które używają czterech cyfr do ich wersjonowania, takich jak kręgosłup na szynach ?
JJD
2
@JJD: Zasadniczo powinno być to samo zachowanie. Ostatnia cyfra z czterech może być zwiększana bez ograniczeń, ale trzecia nie (więc ~>0.9.2.3pozwoliłaby na v0.9.2.4 lub v0.9.2.23, ale nie na v0.9.3.0). Jeśli w ograniczeniu podasz tylko 3 cyfry, to czwarta byłaby zasadniczo nieistotna - byłaby ograniczona tylko na podstawie pierwszych trzech określonych przez Ciebie (np. ~>0.9.2Zaakceptowałaby wszystko z serii 0.9.xy, niezależnie od tego, co yjest; ograniczenie jest że 9 nie może być zwiększane).
eldarerathis
3
Istnieje jednak wyjątek od reguły, że „RubyGems zwiększy ostatnią cyfrę w wersji”: gdy podasz jedną cyfrę. Możesz oczekiwać, że „~> 4” będzie oznaczać „dowolną wersję 4 lub wyższą”, ale tak nie jest , więc bądź ostrożny.
hlascelles
2
A co z ~> 0,1 vs ~> 0,1.0? Jeśli pomyślimy o tym jako „nie przeszkadza ci zwiększanie ostatniej cyfry do jakiejś arbitralnej wartości”, ~> 0,1 przekłada się na> = 0,1,0 <1,0,0, podczas gdy ~> 0,1,0 przekłada się na> = 0,1,0 < 0.2.0. Czy to jest poprawne?
Wei
Kiedy widzę projekt GitHub, który mówi, że wymaga ruby> = 2.4.4, czy mogę założyć, że obsługują wszystkie Ruby po 2.4.4, w tym 2.5.1, a nawet Ruby 3? Czy też powinniśmy grać ostrożnie (tj. Zamiast myśleć, że będą obsługiwać wszystkie rubiny po 2.4.4 włącznie, powinienem pomyśleć, że mają na myśli, że nie będą obsługiwać żadnego rubinu przed 2.4.4)?
Henry Yang
3

@millisami Możesz nawet użyć, aby dodać zależności z gemspec, używając pesymistycznego ograniczenia, takiego jak to:

gem.add_runtime_dependency "thor", "~> 0.18.1"

Jeśli nie wiesz zbyt wiele na temat tworzenia klejnotów lub dopiero się w to wkraczasz, oto kilka dobrych referencji:

  1. Samouczek, który uczy, jak stworzyć swój własny RubyGem, standardowe praktyki z nim związane oraz jak go załadować, aby inni mogli go zainstalować.
  2. Jak stworzyć klejnot od podstaw za pomocą programu Bundler
strangeloops
źródło
1
Pierwszy link to 404
Petr Gazarov