如何在Ruby中使用&阻止

时间:2015-10-18 02:11:03

标签: ruby block yield

我试图在Ruby中使用块,我有这个代码:

  def positions
    return horizontally_position if orientation == "horizontally"
    vertically_position
  end

  def horizontally_position
    res = []
    for x in position[0]..end_coord(0) 
      res << [x, position[1]]
    end
    return res
  end

  def vertically_position
    res = []
    for y in position[1]..end_coord(1)
      res << [position[0], y]
    end
    return res
  end

似乎有重复的代码,并希望使用块或产量提高性能,但不知道如何!

这样做:

  def positions
    return h_v_position(0, {[x, position[1]]}) if orientation == "horizontally"
    h_v_position(1, {[position[0], y]})
  end

  def h_v_positions(coord, &block) 
    res = []
    for x in position[coord]..end_coord(coord) 
      res << block.call
    end
    return res
  end

但是没有工作......有什么帮助吗?

2 个答案:

答案 0 :(得分:1)

如果需要处理块参数,可以使用隐式yield:

def foo
  yield
end

或者您可以明确传递该块并使用block.call调用它:

def foo(&block)
  block.call
end

因此,如果您将res << &block替换为res << block.call,则应正确调用该块。

答案 1 :(得分:0)

在google中进行思考和搜索后,我找到了最好的方法,并了解如何在Ruby中使用&blocksyields

在最重要的是,我的问题是这个重复的代码:

  def horizontally_position
    res = []
    for x in position[0]..end_coord(0) 
      res << [x, position[1]]
    end
    return res
  end

  def vertically_position
    res = []
    for y in position[1]..end_coord(1)
      res << [position[0], y]
    end
    return res
  end
  

我做的第一件事就是使用yield

来避免重复的代码
  def position_by(coord) # ²
    res = []
    for n in position[coord]..end_coord(coord) 
      res <<  yield(n) # ³
    end
    return res
  end  

  def horizontally_position # ¹
    position_by(0) { |n| [n, position[1]] } # ⁴
  end

  def vertically_position # ¹
    position_by(1) { |n| [position[0], n] } # ⁴
  end

¹调用此方法时,会调用position_by(1)position_by(0) ²此方法将开始执行,并涉及<< yield(n) ...
³它将再次来到vertically_position“或horizontally_position,并将替换yield中的position_by以获取horizontally_position(或vertically_position中括号中的代码对不起,我们很抱歉。

完成后我看到了方法position_by(coord)并希望稍微重构一下。

  

第一个重构,使用yield

  def position_by(end_coor)
    position[end_coor]..end_coord(end_coor).map do |x|    
        yield x
    end
  end
  

然后使用&block

  def position_by(coord, &block) # ⁵
        (position[coord]..end_coord(coord)).map &block
  end 

⁵这里我们将每个位置映射到& block,并且一个块可以是[x,position(1)]或[position(0),y],其中x或者将被替换为位置[coord]对应。