【问题标题】:Recursive/nested yield递归/嵌套收益率
【发布时间】:2015-04-29 17:22:43
【问题描述】:

我有以下几种使用 Nokogiri 编辑深度嵌套的 XML 结构的方法。我想在深入研究结构时删除一些样板,所以我想重构这些方法。

这里是方法

def create_acl(acl_name, addresses)
  connection.rpc.edit_config do |x|
    # `x` is a `Nokogiri::XML::Builder` object.
    x.configuration do
      x.firewall do
        x.family do
          x.inet do
            x.filter do
              x.name(acl_name)
              add_acl_whitelist(x, addresses)
              add_acl_blacklist(x)
            end
          end
        end
      end
    end
  end
end

def link_options
  connection.rpc.edit_config do |x|
    # `x` is a `Nokogiri::XML::Builder` object.
    x.configuration do
      x.interfaces do
        x.interface do
          x.name(interface['interface'])
          x.send(:'ether-options') do
            x.send(:'802.3ad') do
              additional.each_pair { |attr, value| x.send(attr) { x.send(value) } }
            end
          end
        end
      end
    end
  end
end

我想我想把它们重构成这样:

def create_acl(acl_name, addresses)
  edit_config(:firewall, :family, :inet, :filter) do |x|
    x.name(acl_name)
    add_acl_whitelist(x, addresses)
    add_acl_blacklist(x)
  end
end

def link_options
  edit_config(:interfaces, :interface) do |x|
    x.name(interface['interface'])
    x.send(:'ether-options') do
      x.send(:'802.3ad') do
        additional.each_pair { |attr, value| x.send(attr) { x.send(value) } }
      end
    end
  end
end

def edit_config(*parents, &block)
  connection.rpc.edit_config do |x|
    # Recursively yield each item in `parents` to x, then yield the given
    # block...
    #
    # Something like this, only with yielding?
    #
    # parents = parents.unshift(:configuration)
    # parents.each { |method| x.send(method, &block) }
  end
end

关于如何嵌套可以传递给该方法的可变数量的产量有什么想法吗?如果没有,关于如何在这些方法中重构样板文件有什么其他想法吗?

提前致谢!

【问题讨论】:

    标签: ruby recursion nokogiri yield


    【解决方案1】:

    看看这种风格是否有帮助:

    puts "Usual nested way : "
    3.times do |x|
        x.times do
            x.times do 
                puts x
            end
        end
    end
    # => 
    # 1
    # 2
    # 2
    # 2
    # 2
    
    puts "Using recursion : "
    def compact_nested_blocks(*funcs, &leaf_block)
        3.times do |x| # Place the call to your parent block (connection.rpc ...).
            sub_block(x, *funcs, &leaf_block)
        end
    end
    
    def sub_block(obj, *funcs, &leaf_block) 
        obj.send(funcs.shift) do
            funcs.empty?? yield(obj) : sub_block(obj, *funcs, &leaf_block)
        end
    end
    
    # Call it with your methods instead of 'times'.
    compact_nested_blocks(:times, :times) do |x|
        puts x
    end
    # => 
    # 1
    # 2
    # 2
    # 2
    # 2
    

    我无法在本地使用您的代码对其进行测试。更换您需要的核心线,看看是否足够。

    【讨论】:

      猜你喜欢
      • 2011-05-14
      • 2013-09-28
      • 2014-10-20
      • 2019-04-14
      • 1970-01-01
      • 2010-12-21
      • 1970-01-01
      • 2020-11-20
      • 2023-04-08
      相关资源
      最近更新 更多