Почему процедуры можно вызывать с помощью === в Ruby 1.9?
-
12-12-2019 - |
Вопрос
Эта статья упоминает 4 способа вызова процедур в Ruby 1.9, и === — один из них.Я вообще не понимаю, почему это делается именно так.Имеет ли это какое-либо отношение к обычному значению === (вопрос, являются ли два объекта одним и тем же объектом)?
irb(main):010:0> f =-> n {[:hello, n]} => # irb(main):011:0> f.call(:hello) => [:hello, :hello] irb(main):012:0> f === :hello => [:hello, :hello] irb(main):013:0> Object.new === Object.new => false irb(main):014:0> f === f => [:hello, #]
Решение
Это значит, что объект 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
имеет больше смысла, но думайте о нем как об инструменте для создания собственного принадлежит операторы, как в моем примере выше;Я определил объект, который может определить, если что-то принадлежит набор четных чисел.
Другие советы
Обратите внимание, что ===
в 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
:«Случайный равенство - для объекта класса, фактически то же самое, что и призыв #==, но обычно переопределяется потомками, чтобы обеспечить значимую семантику в случае утверждений».
К сожалению, несмотря на то, что он состоит из трех =
, это не имеет ничего общего с равенством даже отдаленно :-D