Почему процы могут вызываться с === в ruby ​​1.9? - PullRequest
6 голосов
/ 13 марта 2012

В этой статье упоминается 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, #]

Ответы [ 4 ]

5 голосов
/ 13 марта 2012

Обратите внимание, что === в 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
4 голосов
/ 13 марта 2012

Это то, что документы должны сказать :

Это позволяет объекту proc быть целью предложения when в операторе case.

Это, возможно, надуманный пример:

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, но думайте о нем как о инструменте для создания собственных операторов , как в моем примере выше;Я определил объект, который может определить, принадлежит ли множество четных чисел.

2 голосов
/ 13 марта 2012

Эта функция полезна в случае построения, когда вам нужно что-то посчитать при сравнении.

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
0 голосов
/ 13 марта 2012

Имеет ли он какое-либо отношение к обычному значению === (спрашивая, являются ли два объекта одним и тем же объектом)?

На самом деле, это распространенное заблуждение о === в Ruby. Это на самом деле не строго для Object#object_id сравнения (хотя таково его поведение во многих распространенных вызовах). В Ruby === - это регистр , .

Вот описание === из Object: "Case Equality - для класса Object, фактически то же самое как вызов # ==, но обычно переопределяется потомками обеспечить содержательную семантику в операторах case. "

К сожалению, хотя он состоит из трех =, он не имеет ничего общего даже с равенством: -D

...