2010-12-28 34 views
11

En rubí, se puede hacer esto:Ruby - primordial/permitiendo la asignación múltiple (por ejemplo, `a, b, c = d, e, F`)

d = [1, 2, 3] 
a, b, c = d 

a, b, y c, recibirán los valores 1, 2 y 3, respectivamente.

d, en este caso en un Array y Ruby sabe asignar su contenido a a, b, y c. Pero, si d eran una Fixnum, por ejemplo, sólo a sería asignado al valor de d mientras bc y se asignaría nil.

¿Qué propiedades de d permiten que se lo utilice para tareas múltiples? En mi exploración hasta ahora, solo he podido hacer que las instancias de las subclases de Array se comporten de esta manera.

Respuesta

11

Esta es una característica muy indocumentada, y la usaría con precaución, pero aquí vamos. Del libro The Ruby Lenguaje de Programación:

Cuando hay múltiples lvalues ​​y sólo un único valor de lado derecho, Ruby intenta ampliar el valor de lado derecho en una lista de valores para asignar . Si el valor es una matriz , Ruby expande la matriz para que cada elemento se convierta en su propio valor r. Si el valor no es una matriz pero implementa un método to_ary, Ruby invoca ese método y luego expande la matriz que devuelve.

en Ruby 1.8 es el método to_ary, en Ruby 1.9 documentación dice que llama to_splat, pero no he probado (sin 1,9 en esta máquina) no funcionó como se esperaba. Entonces, debe definir un método to_ary en su objeto.

class Week 
    def to_ary 
    %w(monday tuesday wednesday thursday friday saturday sunday) 
    end 
end 

mon, tue, wed, thu, *weekend = Week.new 

* %w(...) es una notación especial para un conjunto de palabras, si usted es perezoso para escribir ['monday', 'tuesday' ...]

+0

Creo Trate de Ruby! usa 1.9. O puede descartar totalmente eso y usar jQuery RVM. –

+0

:) En realidad fui a 'rvm install 1.9.1' después de la respuesta – Chubas

7

¿Qué propiedades de d permiten que se lo utilice para tareas múltiples?

d tiene que haber un Array o ser convertible a uno. OIA debe ser una instancia de la clase Array (o cualquiera de sus subclases) o responder al mensaje to_ary:

def (not_an_array = Object.new).to_ary; [:foo, :bar, :baz] end 

foo, bar, baz = not_an_array 

foo # => :foo 
bar # => :bar 
baz # => :baz 

Tenga en cuenta que este es un ejemplo de un patrón más general en Ruby: casi todos los métodos en ruby que esperar un Array, un String, un Integer o una Float también aceptará un objeto que responde a to_ary, to_str, to_int o to_float. ¡Y sus propios métodos también deberían, por cierto!

Cuestiones relacionadas