Heim  >  Fragen und Antworten  >  Hauptteil

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中文网2759 Tage vor589

Antworte allen(2)Ich werde antworten

  • 高洛峰

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

    订正

    题主给出的程序有点小错误,订正后如下,注意 visit &blockprint ' ' * 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}" }

    回答

    将第15行按题主意思由

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

    改为

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

    后,程序输出结果是一致的。

    结论

    问题不存在。

    Antwort
    0
  • PHP中文网

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

    每行代码执行的时候都有一个上下文,在上下文中存储着这行代码可以访问的一些变量。块可以访问定义时的上下文,在你的例子中这个块定义在全局,所以可以访问到全局变量,不过这里的全局变量只有ruby_tree(也有一些语言内置的就不说了)。但是没有block这个变量,所以在块内是不能访问的,会报类似不变量或方法存在的错误。

    换一个解译,如果用远古的C语言类似的例子说的话,就是block这个变量是个实参,而你在块中要使用与其对待的形参node这个变量。

    Antwort
    0
  • StornierenAntwort