2009-03-20 13 views
56

Jakie są symbole potoku w Ruby?Co to za symbole rurek w Ruby?

uczę Ruby i RoR, pochodzących z PHP i Java tle, ale stale napotykając kodu tak:

def new 
    @post = Post.new 

    respond_to do |format| 
    format.html # new.html.erb 
    format.xml { render :xml => @post } 
    end 
end 

Jaki jest |format| część robi? Jaka jest odpowiednia składnia tych symboli potoku w PHP/Java?

Odpowiedz

42

Są to zmienne wydane dla bloku.

def this_method_takes_a_block 
    yield(5) 
end 

this_method_takes_a_block do |num| 
    puts num 
end 

Który wyprowadza "5". Bardziej tajemniczy przykład:

def this_silly_method_too(num) 
    yield(num + 5) 
end 

this_silly_method_too(3) do |wtf| 
    puts wtf + 1 
end 

Wyjście to "9".

+0

gdzie 'wtf' idzie, gdy kończy się blok' | wtf | '? – ThorSummoner

+0

Jest on ograniczony do bloku, więc jest niedostępny poza nim. Innymi słowy: odchodzi. –

+0

Jeśli jest zmienna? Musi tak być, inaczej nie mam pojęcia, jak Vagrantfile może ich użyć jako metody konfiguracji. – ThorSummoner

5

Kod z do do end definiuje Ruby block. Słowo format jest parametrem bloku. Blok jest przekazywany wraz z wywołaniem metody, a wywołana metoda może przyjmować wartości yield do bloku.

Zobacz dowolny tekst na temat Ruby, aby uzyskać szczegółowe informacje, jest to podstawowa cecha Ruby, którą zobaczysz przez cały czas.

+1

Nie, kod pomiędzy do i końca jest blokiem ruby. Terminy między pionowymi kreskami są parametrami tego bloku. – rampion

+0

IIRC, składnia potoku jest pożyczona od Smalltalk. –

+0

Tak, z wyjątkiem Smalltalk właśnie użył jednej rury. – Chuck

3

Równowartość w Javie byłoby coś

// Prior definitions 

interface RespondToHandler 
{ 
    public void doFormatting(FormatThingummy format); 
} 

void respondTo(RespondToHandler) 
{ 
    // ... 
} 

// Equivalent of your quoted code 

respondTo(new RespondToHandler(){ 
    public void doFormatting(FormatThingummy format) 
    { 
     format.html(); 
     format.xml(); 
    } 
}); 
+0

Brent, jeśli masz na myśli, że wersja Java jest gadatliwa i rozwlekła - tak, zgodzę się z tobą. Ale znowu jest to mniej idiomatyczna konstrukcja w Javie. Ruby używa go cały czas, Java mniej. –

+0

the format.html(); format.xml(); część prawdopodobnie byłaby bardziej jak instrukcja switch, ponieważ włączasz żądany format. – jonnii

+0

Czystszym przykładem jest odpowiednik konstrukcji w JavaScript: respond_to (nowa funkcja (format) {format.html(); format.xml();}); Uważam, że brak obsługi prawdziwego funktora Javy jest naprawdę irytujący; w ogóle nie są trudne do użycia - chyba że nauczyłeś się ich z anonimowymi zajęciami w Javie! –

2

parametry dla sit bloku między | symboli.

5
@names.each do |name| 
    puts "Hello #{name}!" 
end 

w http://www.ruby-lang.org/en/documentation/quickstart/4/ towarzyszą następujące wyjaśnienie:

each jest metodą, która przyjmuje blok kodu następnie uruchamia tego bloku kodu dla każdego elementu na liście, a bit między do i end to taki blok. Blok jest jak anonimowa funkcja lub lambda. Zmienna między znakami potoku jest parametrem dla tego bloku.

Co się dzieje tutaj, dla każdego wpisu na liście, name jest związany z tym elementem listy, a następnie wyrażenie puts "Hello #{name}!" jest uruchamiane z tą nazwą.

24

Na początku było to dla mnie bardzo dziwne, ale mam nadzieję, że to wyjaśnienie/walkthru ci pomoże.

Dokumentacja touches the subject, w całkiem dobry sposób - jeśli moja odpowiedź nie pomoże, jestem pewien, że ich przewodnik będzie.

Najpierw odpalić Interaktywny interpreter Ruby wpisując irb w swojej skorupie i uderzanie Wprowadź.

Rodzaj coś takiego:

the_numbers = ['ett','tva','tre','fyra','fem'] # congratulations! You now know how to count to five in Swedish. 

tak, że mamy tablicę do zabawy.Następnie tworzymy pętlę:

the_numbers.each do |linustorvalds| 
    puts linustorvalds 
end 

Wypisze wszystkie liczby oddzielone znakami nowej linii.

W innych językach trzeba by napisać coś takiego:

for (i = 0; i < the_numbers.length; i++) { 
    linustorvalds = the_numbers[i] 
    print linustorvalds; 
} 

Ważne rzeczy do odnotowania jest to, że |thing_inside_the_pipes| może być wszystko, tak długo jak używasz go konsekwentnie. I zrozumcie, że to pętle, o których mówimy, to było coś, czego nie dostałem dopiero później.

+2

W niektórych "innych językach" (Python) piszesz "dla linustorvalds w the_numbers do drukowania linustorvalds". Może nieco bardziej intuicyjny. –

+1

Absolutnie poprawne. Wybrałem składnię w stylu C, ponieważ podejrzewam, że więcej osób przychodzących na ruby ​​jest tego obeznanych, ale mam nadzieję, że oni również przeczytają twój komentarz. –

+0

Dziękuję. Sekcja "inne języki" pomogła mi zrozumieć, co się dzieje. +1. – rayryeng

1

Żeby było jeszcze wyraźniejsze, jeśli to konieczne:

pręty rurowe zasadniczo dokonać nowej zmiennej do przechowywania wartości wygenerowanego z wywołania metody przed. Coś podobnego do:

Oryginalna definicja metodę:

def example_method_a(argumentPassedIn) 
    yield(argumentPassedIn + 200) 
end 

Jak to działa:

example_method_a(100) do |newVariable| 
    puts newVariable; 
end 

To prawie tak samo jak pisanie to:

newVariable = example_method_a(100) 
puts newVariable 

wher e, newVariable = 200 + 100 = 300: D!