2014-10-24 2 views
0

Ruby에서 매크로를 사용할 수 없다는 것을 알고 있지만, 해결 방법을 모르는 상황이 발생했습니다.Ruby 매크로 텍스트 대체

나는 거의 동일한 두 가지 방법이 있으며 두 변수 이름 만 다릅니다. 특히, |n||m|을 외부 및 내부 upto 루프로 바꿨습니다. I는 전체 "X"값의 완전한 행에 대한 5 × 5 빙고 보드 의하면있어 첫 번째 방법, 및 "X"값의 전체 열의 두 번째 방법에서는 검사

def self.check_across 
    0.upto(4) do |n| 
    test = 0 
    0.upto(4) { |m| if @@bingo_board[n][m] == "X" then test += 1 end } 
    if test == 5 then return true end 
    end 
    return false 
end 

def self.check_down 
    0.upto(4) do |m| 
    test = 0 
    0.upto(4) { |n| if @@bingo_board[n][m] == "X" then test += 1 end } 
    if test == 5 then return true end 
    end 
    return false 
end 

.

나는 SAS에서이 방법을 %macro으로 감쌀 수 있음을 알고 있습니다. 루비, 나는이 작동하지 않습니다 알아,하지만 난 할 노력하고있어 이것이다 :

def self.check(x, y) 
    0.upto(4) do |x| 
    test = 0 
    0.upto(4) { |y| if @@bingo_board[n][m] == "X" then test += 1 end } 
    if test == 5 then return true end 
    end 
    return false 
end 

example.check(n, m) # same as .check_across 
example.check(m, n) # same as .check_down 

물론,이 n 때문에 작동하지 않고 m 외부에 존재하는 변수 이름으로 간주 될 것이다 방법의.

+1

당신은'define_method'를 사용할 수 있지만, 추상화 할 필요가있는 것은'@@ bingo_board [n] [m]'을 검색하는 것입니다. 그래서 정말 args를 뒤집는 두 개의 작은 메소드가 필요합니다 , 그리고 루프와 테스트를 수행하는 더 큰 방법. 또는 두 개의 간단한 람다를 루프/테스트 메서드에 전달할 수 있습니다 (아마 내 환경 설정,하지만 그 방법을 롤백). –

답변

2

블록을 사용하여 비슷한 결과를 얻을 수 있습니다. 예를 들어

,

def check 
    0.upto(4) do |i| 
    test = 0 
    0.upto(4) do |j| 
     # hand control of how to deal with indices over to the calling method 
     if yield(i,j) == 'X' 
     test += 1 
     end 
    end 
    return true if test == 5 
    end 
    false 
end 

def check_across(board) 
    check do |i,j| 
    # implementing logic for accessing rows 
    board[i][j] 
    end 
end 

def check_down(board) 
    check do |i,j| 
    # implementing logic for accessing columns 
    board[j][i] 
    end 
end 

그리고 빠른 전성 검사 :

a = [ 
%w(O O O O O), 
%w(O O O O O), 
%w(O O O O O), 
%w(O O O O O), 
%w(O O O O O) 
] 

b = [ 
%w(O O O O O), 
%w(O O O O O), 
%w(X X X X X), 
%w(O O O O O), 
%w(O O O O O) 
] 

c = [ 
%w(O O O X O), 
%w(O O O X O), 
%w(O O O X O), 
%w(O O O X O), 
%w(O O O X O) 
] 

check_across(a) #=> false 
check_across(b) #=> true 
check_across(c) #=> false 

check_down(a) #=> false 
check_down(b) #=> false 
check_down(c) #=> true 
+1

+1, 화려한 평소와 같이. –

+0

정확히! 루비는 굉장히 강력합니다.하지만 - 때때로 다른 방식으로 생각하게 만듭니다. –

+0

대시 보드 등에서 무언가를 고쳐야하지 않습니까? –

1

당신이 테스트되지 않은 코드를 시도 할 수 있습니다 :

def self.check_across 
    @@bingo_board.each do |n| 
    return true if n.all?{ |m| m == 'X' } 
    end 

    false 
end 

def self.check_down 
    @@bingo_board.transpose.each do |m| 
    return true if m.all?{ |n| n == 'X' } 
    end 

    false 
end 

transpose이있는 좋은 방법입니다 이런 종류의 문제에 유용합니다. all?을 사용하면 배열의 모든 요소가 동일한 지 쉽게 확인할 수 있습니다.

def self.check_across 
    @@bingo_board.any?{ |n| 
    n.all?{ |m| m == 'X' } 
    } 
end 

def self.check_down 
    @@bingo_board.transpose.any?{ |m| 
    m.all?{ |n| n == 'X' } 
    } 
end 

any?이 모든 요소가 조건을 일치하고 true를 반환 여부를 발견하는 데 유용합니다 : 그것은 그처럼 보이는


는에 DRY'd 할 수 있습니다. 이 경우 행 또는 열이 모두 'X'인지 여부입니다.

+0

나는 그것을 좋아한다. + 5chs –

+0

고마워. 너무 늦었고 아침에 카페인을 갖지 않았기 때문에 테스트되지 않았습니다. –