2012-01-11 22 views
11

he visto este código en un tutorial rieles que estoy haciendorieles/rubí "y return false" sintaxis

def access_denied 
    redirect_to login_path, :notice => "Please log in to continue" and return false 
end 

Antes de rieles de aprendizaje, hice una gran cantidad de investigación rubí y ninguno de los libros Leí cubierto esta sintaxis "y devolver falso" pasando aquí. No puedo encontrar ninguna mención de ello en la sintaxis de los rieles, ¿alguien puede proporcionar un enlace o alguna explicación que aclare esto?

No entiendo la necesidad del "y" aquí porque pensé que ruby ​​siempre devolvería la última expresión evaluada.

+0

Oh, pensé que estabas preguntando * por qué * se usaría. En cualquier caso, si está siendo utilizado por un filtro como se describe en mi respuesta, sea muy cauteloso. –

Respuesta

21

El y es no sólo para que usted sea capaz de escribir el retorno falsa en la misma línea que la declaración anterior.

Es equivalente a hacer esto:

redirect_to login_path, :notice => "Please log in to continue" 
return false 

no es exactamente lo mismo, porque con el "y" sería solamente devolver false si el redirect_to método devuelve algo que no es nula o falso pero como casi siempre devuelve algo que no es nil ni falso entonces el lado derecho de la instrucción siempre se ejecuta (y falso se devuelve).

El y en Ruby es sólo un alias para & & y se comporta exactamente igual que con una sola diferencia, que tiene una prioridad más baja que el resto de piezas de la declaración, por lo que primero se evalúa lo que está en su izquierda y luego se aplica. Ruby también tiene o que es lo mismo que || pero con una precedencia menor en expresiones.

+1

Si alguna vez quiere agregar un retorno que siempre se ejecuta pero ** no está seguro de que la primera expresión siempre será no-falsa, también puede usar un punto y coma en vez de 'y', así:' do_ algo argumento, argumento; devolver falso' –

2

Este tipo de construcción solía usarse con un filtro, cuando se esperaban los valores de retorno del filtro. El false detendría el procesamiento de solicitud normal.

lo tanto, si un controlador se veía así:

class FooController < ActionController::Base 
    before_filter :access_denied 
    # etc. 
end 

Ninguna de las acciones del controlador correrían; este método fue probablemente diseñado para ser llamado de un filtro, como:

def check_access 
    return access_denied unless current_user.has_access 
end 

se ignoran Estos valores de retorno de filtro días.

Se podría utilizar como un método normal en una acción para detener el procesamiento de la acción y regresar después de la redirección, por lo que no hay otra lógica/representación/etc. se ejecuta dentro del controlador.

3

redirect_to login_path, :notice => "Please log in to continue" es una expresión normal en Ruby que no devuelve falso (o nil, ver el source code), por lo que la ejecución del programa continúa (para comprobar la segunda parte después de Y) y return false puede ser ejecutado.

1

Documentación sobre operadores: Under the "Defined?, And, Or, and Not" section

Usando and es útil para encadenar operaciones conexas juntos hasta que uno de ellos devuelve nil o false. Puede usarlo como lo mostró en su pregunta o también puede usarlo para cortocircuitar la línea de código.

# Short circuit example 
blog = Blog.find_by_id(id) and blog.publish! 

El blog sólo se pone .publish! llama en él si el find_by_id fue exitosa.

En su ejemplo:

def access_denied 
    redirect_to login_path, :notice => "Please log in to continue" and return false 
end 

Están simplemente utilizando para escribir el código de forma más compacta en una sola línea.

Sin embargo, también es útil para una acción del controlador donde se vea representación basada en los condicionales y no quiere conseguir rieles "múltiple hace" aviso:

def show 
    if something 
    render :partial => 'some_partial' 
    end 

    render :partial => 'some_other_partial' 
end 

Carriles le dará una advertencia if something devuelve verdadero ya que tiene múltiples declaraciones de representación que se evalúan en la acción. Sin embargo, si lo cambió a

if something 
    render :partial => 'some_partial' and return 
end 

, le permitiría detener la ejecución de la acción.

Cuestiones relacionadas