[英]How to use &block in Ruby
我正在嘗試在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
但是沒有用..有幫助嗎?
如果需要處理塊參數,則可以使用隱式yield:
def foo
yield
end
或者您可以顯式傳遞該塊,然后使用block.call
調用:
def foo(&block)
block.call
end
因此,如果將res << &block
用res << block.call
,則應正確調用該塊。
經過思考並在Google中搜索后,我找到了實現此目的的最佳方法,並了解了如何在Ruby中使用&blocks
和yields
。
更重要的是,我的問題是重復的代碼:
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]。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.