2015-10-18 2 views
1

Я пытаюсь использовать блоки в 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 

Но это не работа .. есть любая помощь?

+0

Если я интерпретирую это право, я думаю, вместо того, чтобы передавать блок, вы просто хотите передать массив '[x, position [1]]' или '[position [0], y]'.Кроме того, при использовании блока в Ruby вы передаете аргумент, как вы, но внутри метода вы вызываете блок с помощью 'block.call'. Но блоки - это блоки. Это те '{материал здесь}', который вы использовали бы для передачи конкретных аргументов методам для использования. Но, в вашем случае, похоже, что вы передаете информацию в массиве для хранения в другом массиве с именем 'res' и возвращаете это. –

+0

Спасибо за это, я нашел решение своей проблемы, я отправлю его через несколько минут. –

ответ

0

После поиска и поиска в google я нашел лучший способ сделать это и понял, как использовать &blocks и yields в Ruby.

В bigining, моя проблема была в этом повторенное код:

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 

Первое, что я делаю aboid повторный код был использовать 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 

¹ When этот метод будет вызван, он будет звонить в 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, и блок может быть [х, положение (1)] или [ position (0), y], где x или будет заменено для соответствующей позиции [координаты].

1

Если вам нужно обработать аргументы блока вы можете использовать неявный выход:

def foo 
    yield 
end 

или вы можете передать блок в явном виде и назвать его block.call:

def foo(&block) 
    block.call 
end 

Так что если вы замените res << &block с res << block.call блок должен быть вызван должным образом.

Смежные вопросы