Właśnie zacząłem uczyć się Ruby i Ruby on Rails i natknąłem się na kod walidacyjny, który używa zakresów:
validates_inclusion_of :age, :in => 21..99
validates_exclusion_of :age, :in => 0...21, :message => "Sorry, you must be over 21"
Na początku myślałem, że różnica polega na włączeniu punktów końcowych, ale w dokumentacji API, którą sprawdziłem, nie miało znaczenia, czy tak jest, ..
czy ...
: zawsze zawierał punkty końcowe.
Jednak przeprowadziłem kilka testów w irb i wydawało się, że wskazuje to na ..
oba punkty końcowe, podczas gdy ...
tylko dolną granicę, ale nie górną. Czy to jest poprawne?
(1..10).include? 10 #=> true
i(1...10).include? 10 #=> false
(a..b) != (a...(b+1))
pomimo tego, że ich reprezentacje tablicowe są równe (gdy a, b ∈ ℤ). Zaktualizowałem nieco moją odpowiedź, aby to rozwinąć.inject
pochodzi zEnumerable
któregoRange
obejmuje;Enumerable
wykorzystuje#each
, któryRange
implementuje . Lista wygenerowana przezRange#each
nigdy nie jest zawarta w samymRange
obiekcie.To jest poprawne.
Składnia z trzema kropkami jest mniej powszechna, ale jest ładniejsza niż
(1..10-1).to_a
źródło
..
jest bardziej powszechne i dlatego mniej jest dla niego preferowane?(a..b-1) != (a...b)
chociaż ta odpowiedź sugeruje, że tak jest.Dokumentacja API opisuje teraz to zachowanie:
Innymi słowy:
źródło
a...b
wyklucza wartość końcową, aa..b
zawiera wartość końcową.Podczas pracy z liczbami całkowitymi
a...b
zachowuje się jaka..b-1
.Ale tak naprawdę zakresy różnią się na osi liczb rzeczywistych .
Możesz to zobaczyć, zwiększając w krokach ułamkowych.
źródło
a
&b
są liczbami całkowitymi, zakresy są różne. Tylko wtedy, gdy każdy jest konwertowany na tablicę, są takie same. W zaakceptowanej odpowiedzi istnieje konkretny kontrprzykład... i ... oznaczają zakres.
Po prostu zobacz to w irb:
źródło