ruby block问题
PHP中文网
PHP中文网 2017-04-24 09:11:17
0
2
613

做七周七语言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中文网

认证高级PHP讲师

répondre à tous(2)
小葫芦

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.

Ty80

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.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal