Pregunta

Una respuesta a una pregunta que hice ayer aquí fue el siguiente fragmento de código Ruby:

def overlap?(r1,r2)
  r1.include?(r2.begin) || r2.include?(r1.begin)
end

def any_overlap?(ranges)
  ranges.sort_by(&:begin).each_cons(2).any? do |r1,r2|
  overlap?(r1, r2)
  end
end

consigo each_cons, pero ¿cuál es la notación &:begin extraño? Sálvame de sintaxis demonios!

Gracias!

¿Fue útil?

Solución

Cuando se anteponga el último argumento de una llamada con & usted está haciendo evidente que usted está enviando un bloque y no un Normal argumento. Ok, en method(&:something), :something es un símbolo, no un proc , por lo Rubí llama automáticamente al to_proc método para obtener un bloque real. Y los carriles chicos (y ahora también de vainilla Rubí) hábilmente definió como:

class Symbol
  def to_proc
    proc { |obj, *args| obj.send(self, *args) }
  end
end

Es por eso que puede hacer:

>> [1, 2, 3].map(&:to_s) # instead of [1, 2, 3].map { |n| n.to_s }
=> ["1", "2", "3"]

[editar] Nota: cuando se da cuenta de que esta construcción es sin azúcar sintáctico pero la infraestructura genérica que ofrece Rubí, nada le impide la implementación de su propia to_proc para otras clases. Nunca me sentí limitado debido &:method permitió sin argumentos?

class Array
  def to_proc
    proc { |obj, *args| obj.send(*(self + args)) }
  end
end

>> ["1", "F", "FF"].map(&[:to_i, 16])
=> [1, 15, 255]

Otros consejos

my_method(&some_value) medios para invocar my_method, pasando some_value en la ranura argumento especial, el proc-ranura, normalmente reservado para el paso de los bloques do-notación.

my_block = lambda { puts "hello" }
(1..3).each(&my_block)

Cualquier objeto que es una Proc o que responde a to_proc se permite ser pasado en el proc-ranura. Si se pasa en un objeto que no es un Proc pero que responde a to_proc, a continuación, Rubí llamará to_proc en el objeto para usted y pasar el resultado en el método.

La implementación de Symbol#to_proc es devolver un proc que, una vez transcurrido un argumento, envía ese argumento el mensaje de que es el símbolo en sí mismo. Por ejemplo, :hello.to_proc.call(my_obj) va a terminar haciendo my_obj.send :hello.

Así my_array.each(&:hello) pasa a :hello each en el proc-ranura (donde un bloque normalmente pasado, si ha utilizado la notación hacer para que un bloque). extremos :hello.to_proc.call(my_array[0]) siendo my_array[0].send :hello, y la misma para todos los índices subsiguientes de my_array.

es igual a:

ranges.sort_by{|r| r.begin}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top