2010-11-28 3 views
0

저는 현재 회계와 관련하여 DSL을 연구 중입니다. 내가 할 수있을 싶은 것은 다음을 호출,Ruby에서 Proc에 할당 된 메소드의 수를 검증 할 수 있습니까?

class Accountant 
    def accountant &block 
    AccountantHelper.class_eval(&block) 
    end 
end 

... 차례로 AccountantHelper 클래스에 블록을 실행 : 현재

accountant do 
    credit @account_1, [email protected] 
    debit @account_2, @amount 
end 

이 다음과 같은 방법을 실행 "신용"을 각각 "직불 카드"방법 :

class AccountantHelper 
    def self.credit account, amount 
    account.credit amount 
    end 

    def self.debit account, amount 
    account.debit amount 
    end 
end 

() (class_eval 사용에 대한 모든 불을 다시 잡아주십시오 -이 결국 단지 프로토 타입입니다!)

목표는 블록이 트랜잭션으로 작동하여 전체 블록을 성공적으로 실행할 수 없으면 아무 것도 수행하지 못하게하는 것입니다. 그러나이 외에도 블록으로 전달 된 데이터의 무결성을 확인해야합니다. 이 경우 블록 내에 "신용"및 "직불"방법이 모두 있는지 확인해야합니다 (이중 신용 계산에는 최소 한 개의 직불 카드가 있어야하고 반대의 경우도 있어야 함). 현재 전화 할 수 있습니다 :

accountant do 
    credit @account_1, @amount 
end 

... 코드는 오류없이 실행됩니다. 계좌를 균형있게 유지하기위한 상응하는 "차변"이 없기 때문에 이것은 나쁜 것입니다.

블록으로 무엇이 전달되는지 확인할 수 있습니까? 아니면 여기서 잘못된 길로 향하고 있습니까?

답변

2

유효성 검사 후 creditdebit 작업을 "지연"동작으로 만들 수 있으므로 유효성 검사 후 래퍼 메서드에 의해 실행됩니다. 여기에 당신과 비슷한 개념의 증거,하지만 메타 프로그래밍 부분없이, 명확성을 위해 생략 :

def transaction 
    yield 
    if @actions.map(&:last).inject(&:+) == 0 
    @actions.each do |account, amount| 
     @accounts[account] += amount 
    end 
    @actions = [] 
    puts 'transaction executed ok' 
    else 
    puts 'balance not zero, rolling back transaction' 
    # rollback (effectively, do nothing) 
    end 
end 

def credit account, amount 
    @actions << [account, amount] 
end 

def debit account, amount 
    @actions<< [account, -amount] 
end 

@actions = [] 
@accounts = {a: 0, b: 0, c: 0} # start with three blank accounts 

transaction do 
    credit :a, 5 
    debit :b, 2 
    debit :c, 3 
end 
#=>transaction executed ok 

p @accounts 
#=>{:a=>5, :b=>-2, :c=>-3} 

transaction do 
    credit :a, 5 
    debit :b, 4 
end 
#=> balance not zero, rolling back transaction 

p @accounts 
#=> {:a=>5, :b=>-2, :c=>-3} 
+0

감사합니다, 그것이 내가 필요 정확히 : 내가 처음에 나는 그는 "신용"을 모두 확인할 필요가 있다고 생각했다 및 "차변"명세서가 블록에 정의되어 있지만 금액을 모두 0으로 합산하는지 간단히 확인하지는 않았습니다. 한 번에 블록의 무결성을 검증하는 간단한 솔루션입니다. – 6twenty

관련 문제