Почему процы могут вызываться с === в ruby 1.9?
В этой статье упоминается 4 способа вызова процедур в ruby 1.9, и === является одним из них. Я не понимаю, почему это было бы сделано так вообще. Имеет ли он какое-либо отношение к нормальному значению === (спрашивая, являются ли два объекта одним и тем же объектом)?
irb (основной):010:0> f =-> n {[: привет, n]} => # irb(основной): 011: 0> f.call (: привет) => [: привет,: привет] irb(основной):012:0> f ===: привет => [: привет,: привет] irb(основной):013:0> Object.new === Object.new => ложь irb (основной):014:0> f === f => [: привет, #]
4 ответа
Вот что должны сказать документы:
Это позволяет объекту proc быть целью
when
оговорка в материалах дела.
Это, возможно, надуманный пример:
even = proc { |x| x % 2 == 0 }
n = 3
case n
when even
puts "even!"
else
puts "odd!"
end
Это работает, потому что case/when
в основном выполняется так:
if even === n
puts "even!"
else
puts "odd!"
end
case/when
проверяет, какую ветку выполнить, вызвав ===
на аргументы when
пункты, выбирая первое, которое возвращает истинное значение.
Несмотря на его сходство с оператором равенства (==
это не более сильная или более слабая форма этого. Я пытаюсь думать о ===
оператор как оператор "принадлежит". Class
определяет его так, что вы можете проверить, принадлежит ли объект классу (т.е. является экземпляром класса или подклассом класса), Range
определяет его, чтобы проверить, принадлежит ли аргумент диапазону (то есть включен ли он в диапазон), и так далее. Это на самом деле не делает Proc
case имеет больше смысла, но думайте о нем как об инструменте для создания своих собственных операторов, как в моем примере выше; Я определил объект, который может определить, принадлежит ли что-то множеству четных чисел.
Обратите внимание, что ===
в Ruby НЕ о равенстве, в отличие от JavaScript. Он специально используется для падежных выражений:
case cats.length
when 42 # Uses 42 === cats.length
puts :uh
when /cool/i # Uses /cool/i === cats.length
puts :oh
when ->(n){ n.odd? || n/3==6 } # Passes cats.length to the proc
puts :my
end
Эта функция полезна в случае построения, когда нужно что-то вычислить при сравнении.
is_odd =-> n { n%2 != 0 }
is_even =-> n { n%2 == 0 }
case 5
when is_even
puts "the number is even"
when is_odd
puts "the number is odd"
end
=> the number is odd
Имеет ли он какое-либо отношение к нормальному значению === (спрашивая, являются ли два объекта одним и тем же объектом)?
На самом деле, это распространенное заблуждение о ===
в рубине. Это на самом деле не строго для Object#object_id
сравнение (хотя таково его поведение во многих общих вызовах). В рубине ===
это случай погружения.
Вот описание ===
от Object
: "Case Equality - для класса Object, фактически то же самое, что вызов #==, но обычно переопределяется потомками, чтобы обеспечить содержательную семантику в операторах case."
К сожалению, хотя он состоит из трех =
, это не имеет ничего общего даже с равенством:-D