2010-09-13 12 views
58

Cuando se utiliza un lenguaje tales como:pasar un hash de una función (* args) y su significado

def func(*args) 
    ... 
end 

¿Cuál es el significado de args *? Buscar en Google esta pregunta específica fue bastante difícil, y no pude encontrar nada.

Parece todos los argumentos que aparecen actualmente en args [0] por lo que me encuentro escribiendo código de defensa tales como:

my_var = args[0].delete(:var_name) if args[0] 

pero estoy seguro de que hay una mejor forma en que estoy perdiendo.

Respuesta

88

El * es el operador splat (o asterisco). En el contexto de un método, especifica una lista de argumentos de longitud variable. En su caso, todos los argumentos pasados ​​a func se pondrán en una matriz llamada args. También puede especificar argumentos específicos antes de que un argumento de longitud variable, así:

def func2(arg1, arg2, *other_args) 
    # ... 
end 

Digamos que llamamos a este método:

func2(1, 2, 3, 4, 5) 

Si inspecciona arg1, arg2 y other_args dentro func2 ahora, se quiere obtener los siguientes resultados:

def func2(arg1, arg2, *other_args) 
    p arg1.inspect  # => 1 
    p arg2.inspect  # => 2 
    p other_args.inspect # => [3, 4, 5] 
end 

En su caso, usted parece estar pasando un hash como un argumento para su func, en cuyo caso, args[0] contendrá el hash, como está observando.

Recursos:


actualización basada en los comentarios de OP

Si desea pasar un hash como un argumento, que debiera No utilice el operador de splat. Ruby le permite omitir los paréntesis, incluyendo aquellos que especifican un Hash (con una advertencia, siga leyendo), en sus llamadas a métodos. Por lo tanto:

my_func arg1, arg2, :html_arg => value, :html_arg2 => value2 

es equivalente a

my_func(arg1, arg2, {:html_arg => value, :html_arg2 => value2}) 

Cuando Rubí ve el operador => en su lista de argumentos, se sabe que tomar el argumento como un hash, incluso sin la {...} notación explícita (tenga en cuenta que este ¡solo se aplica si el argumento hash es el último!).

Si se quiere recoger este hash, usted no tiene que hacer nada especial (aunque es probable que desee para especificar un hash vacía como el valor por defecto en la definición del método):

def my_func(arg1, arg2, html_args = {}) 
    # ... 
end 
+0

Entonces, ¿debo usar la técnica defensiva 'if args [0]' cuando accedo a los params? – shmichael

+0

@shmichael ¿Cómo llamas a tu método? Si no desea que sus argumentos se pongan en una matriz como esta, no use splat. –

+0

Estoy usando la convención de Rails (por ejemplo, 'my_func arg1, arg2,: html_arg => value,: html_arg2 => value2'). Idealmente, me gustaría recibir un hash 'args' *, y no un array' args' * que pueda contener un hash *. – shmichael

-3
def func(map={}) 
    x = map.delete(:y) 
end 
Cuestiones relacionadas