Maison  >  Questions et réponses  >  le corps du texte

ruby block问题

做七周七语言ruby第二天习题的时候要实现一个简单的Tree类,以下代码可以运行,但是把
children.each {|c| c.visit_all(n+1) {|node| puts "-#{node.node_name}"}}
这行的{|node| puts "-#{node.node_name}"}改成&block就跑不起来,请问是为什么?

#!/usr/bin/ruby
class Tree
  attr_accessor :children,:node_name

  def initialize(tree)
    tree.each do |key,value|
      @node_name = key
      @children = value.map {|(key,value)| Tree.new(key => value)}
    end
  end

  def visit_all(n,&block)
    visit &block
    print '  ' * n
    children.each {|c| c.visit_all(n+1) {|node| puts "-#{node.node_name}"}}
  end

  def visit(&block)
    block.call self
  end

end

ruby_tree = Tree.new({
    'grandpa' => {
        'day' => {'child 1' => {},'child 2' => {}},'uncle' => {'child 3' => {},'child 4' => {}}
    }
})

ruby_tree.visit_all(1) {|node| puts "-#{node.node_name}"}

ps: ruby环境是2.1.3

PHP中文网PHP中文网2710 Il y a quelques jours543

répondre à tous(2)je répondrai

  • 高洛峰

    高洛峰2017-04-24 09:13:17

    Correction

    Le programme donné par l'interrogateur comporte une légère erreur. La correction est la suivante Faites attention à l'ordre des lignes visit &block et print ' ' * n :

    .
    #!/usr/bin/ruby
    class Tree
      attr_accessor :node_name, :children
    
      def initialize(tree)
        tree.each do |key, value|
          @node_name = key
          @children = value.map { |key, value| Tree.new(key => value) }
        end
      end
    
      def visit_all(n = 0, &block)
        print '  ' * n
        visit &block
        children.each { |c| c.visit_all(n+1) { |node| puts "-#{node.node_name}" } }
      end
    
      def visit(&block)
        block.call self
      end
    end
    
    ruby_tree = Tree.new({
      'grandpa' => {
        'dad' => { 'child 1' => {},'child 2' => {} },
        'uncle' => { 'child 3' => {},'child 4' => {} }
      }
    })
    
    ruby_tree.visit_all { |node| puts "-#{node.node_name}" }

    Réponse

    Réécrivez la ligne 15 selon le sujet

        children.each { |c| c.visit_all(n+1) { |node| puts "-#{node.node_name}" } }

    a été remplacé par

        children.each { |c| c.visit_all(n+1, &block) }
    Après

    , les résultats du programme sont cohérents.

    Conclusion

    Le problème n’existe pas.

    répondre
    0
  • PHP中文网

    PHP中文网2017-04-24 09:13:17

    Chaque ligne de code a un contexte lors de son exécution, et certaines variables accessibles par cette ligne de code sont stockées dans le contexte. Les blocs peuvent accéder au contexte lorsqu'ils sont définis. Dans votre exemple, ce bloc est défini globalement, vous pouvez donc accéder aux variables globales. Cependant, les seules variables globales ici sont ruby_tree (il existe également des variables intégrées dans certaines langues, ce que je fais). je ne le mentionnerai pas). Cependant, il n'y a pas de variable de bloc, elle n'est donc pas accessible à l'intérieur du bloc, et des erreurs similaires à l'existence d'invariants ou de méthodes seront signalées.

    En d'autres termes, si nous utilisons un exemple similaire de l'ancien langage C, le bloc variable est un paramètre réel, et vous devez utiliser la variable de nœud de paramètre formel pour le traiter dans le bloc.

    répondre
    0
  • Annulerrépondre