2011-06-14 17 views
26

Soy un poco nuevo en Ruby y sigo tratando de entender algunos de los principios del diseño del lenguaje. Si lo hago bien, la llamada de expresión lambda en Ruby debe ser con llaves cuadradas, mientras que la llamada a la función "regular" es con llaves "regulares"/redondas.Llamar/aplicar lambda frente a llamada de función: la sintaxis en Ruby es diferente. ¿Por qué?

¿Hay alguna razón especial por la que la sintaxis sea diferente? O, en otras palabras, ¿por qué debería la persona que llama saber si llaman a una función o aplican una expresión lambda?

Respuesta

23

Porque en Ruby, los métodos no son lambdas (como, por ejemplo, en JavaScript).

Los métodos siempre pertenecen a objetos, se pueden heredar (por subclasificación o mixins), se pueden sobrescribir en la clase de objeto y se puede asignar un bloque (que es un lambda). Ellos tienen su propio alcance para las variables. Ejemplo método de definición:

a = :some_variable 
def some_method 
    # do something, but not possible to access local variable a 
end 

# call with: 
some_method 

Sin embargo lambda/proc se cierres de fricción, tal vez almacenados en una variable - nada más:

a = :some_variable 
some_lambda = lambda{ 
    # do something, access local variable a if you want to 
} 

# call with: 
some_lambda[] 

Rubí combina ambos enfoques con una sintaxis poderosa, por ejemplo, pasando bloques:

def some_method_with_block(a) 
    # do something, call given block (which is a lambda) with: 
    yield(a) ? 42 : 21 
end 

# example call: 
some_method_with_block(1) do |x| 
    x.odd? 
end #=> 42 
+0

muchas gracias! sí, ¡JavaScript era un contraejemplo que tenía en mente! Sería perfecto tener un ejemplo sobre bloques, aunque sé lo que quieres decir, aún siento que podría aprender un poco más de tu respuesta :) – BreakPhreak

+2

Gracias por los comentarios, agregué algunos fragmentos de código :) –

+0

¡perfecto! apreciar - aprendí incluso más de lo esperado :) – BreakPhreak

26

Las llamadas de método Ruby regulares usan () no llaves que son para bloques. Si no te gusta el [] para llamar a un lambda, siempre puedes usar el método call.

Ejemplo:

>> by_two = lambda { |x| x * 2 } #=> #<Proc:[email protected](irb):1> 
>> by_two[5] #=> 10 
>> by_two.call(5) #=> 10 

Editar

En una versión más nueva de Rubí también:

>> by_two.(5) #=> 10 

cuanto a por qué no se puede simplemente hacer by_two(5), cuando ve un rubí bareword primero intenta resolverlo como una variable local y si eso falla como un método.

+0

[1] Reparado en mi pregunta: 'llaves redondas' en lugar de 'rizado'. Mi error. [2] Supongamos que 'by_two' se resuelve primero como una variable. ¿Significa que la razón es simplemente técnica (ajustar el analizador)? ¿No hay aquí algo realmente diferente que pueda aparecer en la llamada lambda frente a llamada de función o algo así? ¿No se refleja la diferencia de algún modo en un nivel de diseño de lenguaje? – BreakPhreak

+0

Ver la respuesta de J -_- L a continuación para [2]. –

8

Si desea soportes, puede hacerlo

by_two = lambda { |x| x * 2 } 
by_two.(5) # => 10 

Tenga en cuenta el . entre by_two y (5).

+0

Eso es útil saber – nterry

Cuestiones relacionadas