Почему процедуры можно вызывать с помощью === в Ruby 1.9?

StackOverflow https://stackoverflow.com//questions/9674749

  •  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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top