2010-09-29 14 views
20

quiero hacer algo similar a esto:Ruby: ¿Pueden los parámetros de la función lambda tener valores predeterminados?

def creator() 
     return lambda { |arg1, arg2 = nil| 
       puts arg1 
       if(arg2 != nil) 
         puts arg2 
       end 
     } 
end 

test = creator() 

test('lol') 
test('lol', 'rofl') 

me sale un par de errores de sintaxis:

test.rb:2: syntax error 
     return lambda { |arg1, arg2 = nil| 
           ^
test.rb:3: syntax error 
test.rb:7: syntax error 
test.rb:14: syntax error 

es esto posible en Ruby? Quiero establecer un valor predeterminado para un parámetro a una función lambda

Respuesta

44

En Rubí 1.9+, puede utilizar cualquiera de las lambdas de estilo antiguo o el nuevo sintaxis "flecha" lambda para establecer un parámetro predeterminado:

ruby-1.9.1-p378 > f = lambda {|x, y=1| puts(x+y) } 
=> #<Proc:[email protected](irb):4 (lambda)> 
ruby-1.9.1-p378 > f.call(1) 
2 
=> nil 
ruby-1.9.1-p378 > f.call(1,5) 
6 
=> nil 

ruby-1.9.1-p378 > f = ->(a, b=5) { puts(a+b) } 
=> #<Proc:[email protected](irb):1 (lambda)> 
ruby-1.9.1-p378 > f.call(1) 
6 
=> nil 
ruby-1.9.1-p378 > f.call(1,2) 
3 
=> nil 
+4

Cuidado, pasar nil no activará el valor predeterminado: – mmell

+0

En Ruby 1.9.3 obtengo un error de sintaxis al poner un espacio entre el stamba lamba y el paréntesis 'f -> (x = 123) {...} '. Funciona bien sin espacio 'f -> (x = 123) {...}'. –

+0

para 'l = -> (k, v, r = nil) {}' levantar un ArgumentError cuando '{a:" A "}. Each & l' pero no error cuando' {a: "A"} each {| k, v | l.call (k, v)} ' –

14

en Ruby 1.8.x puede ordenar de fingir lo largo de las líneas de:

def creator 
    lambda do |*args| 
    raise ArgumentError if args.empty? || args.size > 2 
    arg1, arg2 = args 
    puts arg1 
    puts arg2 unless arg2.nil? 
    end 
end 

>> test = creator 
=> #<Proc:[email protected](irb):2> 
>> test.call("foo") 
foo 
=> nil 
>> test.call("foo", "bar") 
foo 
bar 
=> nil 
>> test.call("foo", "bar", "baz") 
ArgumentError: ArgumentError 

Editar: el ejemplo anterior por defecto el segundo argumento de nil, pero si usted desea tener otro defecto que puede asignar arg2 basado en args.size (p. arg2 = mydefault if args.size < 2). Del mismo modo, si tiene más de dos argumentos, los no especificados se establecerán de manera predeterminada en nil a menos que los asigne usted mismo.

Para Ruby 1.9+ ver otras respuestas.

Cuestiones relacionadas