74 votes

À quoi servent ces symboles de tuyaux en Ruby ?

À quoi servent les symboles de tuyaux en Ruby ?

Je suis en train d'apprendre Ruby et RoR, venant d'un environnement PHP et Java, mais je continue à tomber sur du code comme celui-ci :

def new 
  @post = Post.new

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

Quel est le |format| partie en cours ? Quelle est la syntaxe équivalente de ces symboles pipe en PHP/Java ?

56voto

August Lilleaas Points 25812

Ce sont les variables cédées au bloc.

def this_method_takes_a_block
  yield(5)
end

this_method_takes_a_block do |num|
  puts num
end

Ce qui donne "5". Un exemple plus obscur :

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

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

La sortie est "9".

0 votes

Où se trouve wtf aller quand le |wtf| les extrémités des blocs ?

0 votes

Il s'applique au bloc, il n'est donc pas disponible en dehors de celui-ci. En d'autres termes, il disparaît.

1 votes

S'il est mutable ? Il doit l'être, sinon je n'ai aucune idée de la façon dont les fichiers Vagrantfile peuvent les utiliser comme méthode de configuration.

36voto

Martin Josefsson Points 365

Cela m'a paru très étrange au début, mais j'espère que cette explication vous aidera.

La documentation aborde le sujet Si ma réponse ne les aide pas, je suis sûr que leur guide le fera.

Tout d'abord, lancez l'interpréteur Ruby interactif en tapant irb dans votre coquille et en frappant Enter .

Tapez quelque chose comme :

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

juste pour qu'on ait un tableau avec lequel jouer. Ensuite, nous créons la boucle :

the_numbers.each do |linustorvalds|
    puts linustorvalds
end

Il affichera tous les chiffres, séparés par des lignes de séparation.

Dans d'autres langues, il faudrait écrire quelque chose comme :

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

Les éléments importants à noter sont que le |thing_inside_the_pipes| peut être n'importe quoi, tant que vous l'utilisez de manière cohérente. Et comprenez que nous parlons de loops, c'est une chose que je n'ai comprise que plus tard.

7 votes

Dans certains "autres langages" (Python), on écrit for linustorvalds in the_numbers do print linustorvalds . Un peu plus intuitif, peut-être.

3 votes

Tout à fait exact. J'ai choisi la syntaxe de style C parce que je pense que les personnes qui viennent à Ruby sont plus familières avec cette syntaxe, mais j'espère qu'elles liront aussi votre commentaire.

0 votes

Merci. La section "autres langues" m'a aidé à comprendre ce qui se passait. +1.

7voto

Philip Durbin Points 1943
@names.each do |name|
  puts "Hello #{name}!"
end

à l'adresse http://www.ruby-lang.org/en/documentation/quickstart/4/ est accompagné de cette explication :

each est une méthode qui accepte un bloc de code puis exécute ce bloc de code pour chaque élément d'une liste, et le bit entre do y end est justement un tel bloc. Un bloc est comme une fonction anonyme ou lambda . La variable entre les caractères du pipe est le paramètre de ce bloc.

Ce qui se passe ici est que pour chaque entrée dans une liste, name est liée à cet élément de liste, puis l'expression puts "Hello #{name}!" est exécuté avec ce nom.

6voto

unwind Points 181987

Le code de la do à la end définit un Bloc de rubis . Le mot format est un paramètre du bloc. Le bloc est transmis avec l'appel de méthode, et la méthode appelée peut yield au bloc.

Consultez n'importe quel texte sur Ruby pour plus de détails, il s'agit d'une fonctionnalité essentielle de Ruby que vous verrez tout le temps.

1 votes

Non, le code entre le do et la fin est un bloc ruby. Les termes entre les barres verticales sont des paramètres de ce bloc.

0 votes

IIRC, la syntaxe pipe est empruntée à Smalltalk.

0 votes

Oui, sauf que Smalltalk n'utilisait qu'un seul tube.

3voto

Jon Bright Points 6834

L'équivalent en Java serait quelque chose comme

// 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 votes

Brent, si vous voulez dire par là que la version Java est verbeuse et verbeuse, oui, je suis d'accord avec vous. Mais là encore, il s'agit d'une construction moins idiomatique en Java. Ruby l'utilise tout le temps, Java moins.

0 votes

La partie format.html() ; format.xml() ; serait probablement plus proche d'une instruction switch, puisque vous basculeriez sur le format demandé.

0 votes

Un exemple plus propre est la construction équivalente en JavaScript : respond_to(new function(format) { format.html() ; format.xml() ; }) ; Je trouve le manque de support des vrais foncteurs en Java vraiment ennuyeux ; ils ne sont pas du tout difficiles à utiliser - sauf si vous les avez appris avec les classes anonymes en Java !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X