2013-05-28 20 views
8

prostu zastanawiasz się, czy jest jakiś skrót składnia biorąc dwa procs i łącząc je tak, że wyjście jednego jest przekazywane do drugiego, co odpowiada:Jak połączyć dwa proci w jeden?

a = ->(x) { x + 1 } 
b = ->(x) { x * 10 } 
c = ->(x) { b.(a.(x)) } 

To się przydać podczas pracy z rzeczy jak method(:abc).to_proc i :xyz.to_proc

Odpowiedz

6

więcej cukru, naprawdę nie zalecany w kodzie produkcji

class Proc 
    def *(other) 
    ->(*args) { self[*other[*args]] } 
    end 
end 

a = ->(x){x+1} 
b = ->(x){x*10} 
c = b*a 
c.call(1) #=> 20 
+0

Bardzo ładne! Dlaczego nie poleciłbyś tego? – Gunchars

+0

Ponowne otwarcie wbudowanych klas (takich jak Proc), jest zawsze ryzykowne, ponieważ inne biblioteki prawdopodobnie robią to samo, lub przyszłe zmiany samej Ruby. –

+2

Jestem zaskoczony, że nie ma go gdzieś w standardowej bibliotece. Wydaje się dość użyteczną rzeczą. – Gunchars

2
a = Proc.new { |x| x + 1 } 
b = Proc.new { |x| x * 10 } 
c = Proc.new { |x| b.call(a.call(x)) } 
+0

potrzebuje więcej cukru! – Gunchars

+0

Proszę wyjaśnić, jakiego cukru brakuje w tej odpowiedzi? –

+0

Przepraszam, jeśli nie byłam jasna: dostałeś "a" i "b". Musisz zdobyć 'c'. Możesz oczywiście napisać nowy proces, ale zastanawiam się, czy istnieje krótszy sposób, na przykład 'b.wrap a' lub coś podobnego. – Gunchars

2

można stworzyć operacji Unii jak tak

class Proc 
    def union p 
     proc {p.call(self.call)} 
    end 
end 
def bind v 
    proc { v} 
end 

wtedy można go używać jak to

a = -> (x) { x + 1 } 
b = -> (x) { x * 10 } 
c = -> (x) {bind(x).union(a).union(b).call}