2011-08-17 12 views
9

Ho sempre cercato qualcosa come Python's while/else struct in Ruby per migliorare il mio codice.Equivalente rubino per Python per/

Ciò significa che il ciclo viene eseguito e se la condizione nel ciclo non è stata vera in qualsiasi momento, quindi restituisce il valore nell'istruzione else.

In rubino, posso fare in questo modo:

if @items.empty? 
    "Empty" 
else 
    @items.each do |item| 
    item 
    end 
end 

Così, c'è un modo per migliorare questo?

Grazie in anticipo.

risposta

3

Hm, si potrebbe scrivere come un ternario:

@items.empty? ? 'Empty' : @items.each { |item| item } 

Si consiglia di fare qualcosa di più utile nel tuo blocco, però, dal momento che each viene eseguito per i suoi effetti collaterali e restituisce il ricevitore originale.

aggiornamento secondo il vostro commento: Credo che il più vicino si potrebbe ottenere è qualcosa di simile

unless @items.empty? 
    @items.each { |item| p item } 
else 
'Empty' 
end 
+0

Non mi piace molto solo su una linea. Questo non è più chiaro. Quello che voglio è piuttosto qualcosa mentre/else/end. Forse non è possibile, ma penso che valga la pena la domanda. – Cydonia7

+1

Ho cercato Python's 'while/else' ora, @Zabba ha ragione, il più vicino è probabilmente un' unless..else' se non ti piace la forma ternaria. IMHO non ha senso cercare di tradurre ogni costrutto da una lingua all'altra, ma YMMV. –

+0

Non stavo cercando di tradurre tutto il linguaggio ma penso che questa struct in Python sia veramente utile. Grazie per la risposta :) – Cydonia7

24

Si ricorda che il blocco iteratore restituisce ciò che si mette in esso, che può essere testato per un ulteriore uso.

if arr.each do |item| 
    item.some_action(some_arg) 
end.empty? 
    else_condition_here 
end 
+3

Questo è orribilmente fantastico. –

0

A più o meno funzionale modo:

empty_action = { true => proc{ "Empty"}, 
       false => proc{ |arr| arr.each { |item| item }} } 

empty_action[@items.empty?][@items] 
1

Dal momento che siamo in Ruby, divertiamoci. Ruby ha potente case costrutto, che potrebbe essere utilizzato come questa:

case items 
when -:empty? then "Empty" 
else items.each { |member| 
    # do something with each collection member 
    } 
end 

Ma per far funzionare il codice di cui sopra, dobbiamo modificare la classe nativa Symbol prima. La modifica delle classi native è la specialità di Ruby. Questo deve essere fatto solo una volta, tipicamente in una libreria (gemma), e ti aiuta sempre dopo. In questo caso, la modifica sarà:

class Symbol 
    def [email protected] 
    Object.new 
    .define_singleton_method :=== do |o| o.send self end 
    end 
end 

Questo codice sovraccarica il meno unario (-) utilizzatore di Symbol classe in modo tale, che dire -:sym restituisce una nuova scimmia oggetto vuoto patched con :=== metodo, che viene utilizzato dietro le quinte dalla dichiarazione del caso.