2010-09-29 12 views
20

chcę zrobić coś podobnego do tego:Ruby: Czy parametry funkcji lambda mogą mieć wartości domyślne?

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

test = creator() 

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

Dostaję kilka błędów składni:

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 

to możliwe w Ruby? Chcę ustawić domyślną wartość dla parametru do funkcji lambda

Odpowiedz

44

W Ruby 1.9+, można użyć jednej z lambdas starym stylu lub nowego „strzałki” składni lambda ustawić parametr domyślnie:

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

Ostrożnie, minięcie do zera nie uruchomi wartości domyślnej: – mmell

+0

W Rubim 1.9.3 dostaję błąd składni podczas umieszczania spacji między pchniętym lamba a nawiasem 'f -> (x = 123) {...} '. Działa dobrze bez spacji 'f -> (x = 123) {...}'. –

+0

dla 'l = -> (k, v, r = zero) {}' Podnieście ArgumentError gdy '{a:" A "} każdy & l' ale nie błąd, gdy' {a: "A"} each {| k, v | l.call (k, v)} ' –

14

W Ruby 1.8.x można sortować fałszywych go wzdłuż linii:

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 

Edit: Powyższy przykład domyślne drugi argument do nil, ale jeśli chcesz mieć inny domyślny ty można przypisać arg2 na podstawie args.size (np. arg2 = mydefault if args.size < 2). Podobnie, jeśli masz więcej niż dwa argumenty, nieokreślone z nich będą domyślnie ustawione na nil, chyba że je przypiszesz samemu.

Dla Ruby 1.9+ zobacz inne odpowiedzi.

Powiązane problemy