Pergunta

Este artigo menciona 4 maneiras de invocar procs no ruby 1.9, e === é um deles.Eu não compreendo por que isso poderia ser feito desta forma em todos os.Não tem qualquer relação com o significado normal de === (a perguntar se os dois objetos são o mesmo objeto)?

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, #]
Foi útil?

Solução

Isto é o que os documentos têm a dizer:

É permitir que um objeto proc ser alvo de when cláusula instrução do caso.

Este é, talvez, artificial, exemplo:

even = proc { |x| x % 2 == 0 }
n = 3
case n
when even
  puts "even!"
else
  puts "odd!"
end

Isso funciona porque a case/when basicamente é executado como este:

if even === n
  puts "even!"
else
  puts "odd!"
end

O case/when verifica qual ramo para executar chamando === os argumentos para when cláusulas, escolher o primeiro que retorna um truthy valor.

Apesar de sua semelhança com o operador de igualdade (==) não é mais forte ou mais fraca do que ele.Eu tento pensar da === operador como o "pertence a" do operador. Class define-o de modo que você pode verificar se um objeto pertence a a classe (por exemplo,é uma instância da classe ou subclasse da classe), Range define-a como verificar se o argumento pertence a o intervalo (por exemplo,está incluído no intervalo), e assim por diante.Este não é realmente o Proc caso faça mais sentido, mas pense nisso como uma ferramenta para fazer o seu próprio pertence a operadores, como o meu exemplo acima;Eu defini um objeto que pode determinar se algo pertence a o conjunto dos números pares.

Outras dicas

Note que === em Ruby NÃO é sobre a igualdade, ao contrário de JavaScript.É especificamente usado para o caso de expressões:

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

Esse recurso é útil no caso de construção, quando você precisar calcular algo na comparação.

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

Não tem qualquer relação com o significado normal de === (a perguntar se os dois objetos são o mesmo objeto)?

Na verdade, esse é um equívoco comum sobre === em Ruby.Na verdade, ele não estritamente para Object#object_id comparação (apesar de que é o seu comportamento em muitas invocações).Em Ruby, === é o caso de classificação.

Aqui está a descrição do === a partir de Object:"Caso a Igualdade -- Para a classe de Objeto, na verdade, o mesmo como chamar #==, mas normalmente substituído por descendentes para fornecer semânticas significativas no caso de declarações."

Infelizmente, apesar de a é composto de três =, não tem nada sequer remotamente a ver com a igualdade :-D

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top