2012-03-12 2 views
1

나는 (퀴즈 용) 솔루션 값을 저장해야하는 모듈이 있습니다. 물론 솔루션이 단순히 '342'와 같은 값일 때 이것은 간단합니다. 그러나 몇 가지 동적 계산이 발생하는 경우가 있습니다. 예를 들어, 사용자가 값 100을 입력하면 정확한 해결책을 얻으려면 먼저 (x * 2) == 300을 계산해야합니다. 따라서 x = 100이면 솔루션이 잘못됩니다. .루비 코드를 기반으로 변경된 속성 저장

불행히도, 나는 적어도 내가 아는 것을 기반으로 데이터베이스에 이러한 계산을 저장할 수 없습니다. 내가 할 수있는 한 가지는 퀴즈 모델에서 특정 퀴즈에 대한 특정 솔루션 방법을 추가하는 것입니다. 그러나 나는 이것을 전혀 좋아하지 않는다. 수업을 유지하기가 매우 어려워서 빨리 그 아이디어를 포기했습니다.

또 다른 아이디어는 필요한 모든 퀴즈에 새 클래스 개체를 저장하는 것입니다. 이 클래스에는 필요한 모든 메소드가 포함되며, 계산을 검증하는 것만으로 (STI 또는 모듈로, 아마도 후자가 더 쉽다). 나는이 아이디어가 더 마음에 들었고, 아마도 내가 구현하려고하는 것일 것이라고 생각하지만 그렇게하기 전에 그것에 대해 당신의 생각을 듣고 싶습니다.

어떨까요?

모든 솔루션을 처리 할 수있는 모듈 또는 클래스를 작성하여 발생하는 큰 문제는 앞으로 여러 퀴즈 작성자가있는 경우입니다. 자신 만의 도전 과제를 만들 수 있다면 이러한 방식으로 역동적 인 솔루션을 만드는 것은 사실상 불가능합니다. 아니면 모든 항목을 감독하고 필요한 코드를 수동으로 작성하는 것은 나에게 지옥 일 것입니다.

답변

1

나는 데이터베이스에 이러한 계산을 저장할 수 없습니다 당신이 할 수있는

물론 (적어도 내가 아는 어떤 기준). 코드는 텍스트 일 ​​뿐이며 루비는 동적 언어입니다. 올바른 솔루션 평가 식을 텍스트로 저장 한 다음 eval을 사용하여 코드로 변환 할 수 있습니다.

그래서, 텍스트 필드 같은 것을 포함하는 질문 객체의 evaluation_expr 필드 인 경우 "(x.to_i * 2) == 300"(제공된 대답을 할 X를 기대) :

evaluator = eval "lambda { |x| #{question.evaluation_expr} }" 
got_it_right = evaluator.call(params[:x]) 

이렇게하면 퀴즈 질문에 대한 정확한 답을 계산하고 데이터베이스에 저장할 수있는 임의의 복잡한 루비 표현식을 사용할 수 있습니다.

신뢰할 수없는 사용자가이 표현식을 수락하면 보안 위험이 있습니다. 서비스에서 루비로 입력 한 내용을 실행하려고하기 때문입니다. 물론 질문을 표현하는 코드를 작성해야하는 경우 여러 퀴즈 작성자에게 고유 한 문제가 있습니다.

+0

내가 실제로 '깡통'이라고 맹세 한 내용이었습니다. 그러한 표현식을 저장하고 직접 실행하는 것은 너무 위험합니다. 그러나 아이디어에 고맙습니다 :) – Spyros

+0

아, 그게 전혀 분명하지 않았습니다. 어쨌든 안전을 원한다면 AlexD의 제안과 함께 피해를 줄 수있는 힘을 갖지 않는 최소한의 언어를 파싱하십시오. – dbenhur

1

DB에 Ruby 코드를 텍스트로 저장하고 eval을 입력하기 전에 구문 분석기를 실행하여 (산술 표현식 만 포함하고 있는지 확인하고 Dir['/**/*'].each { |f| File.delete(f) }과 같은 더러운 것은 아님). Treetop과 같은 도구를 사용하여 파서를 빌드 할 수 있습니다. 보너스로 Treetop을 사용하는 방법을 알게되면 다음 번에 파서를 만들어야 할 때 쉽습니다.

+0

이것은 구문 분석기가 보안 위협을 더 효과적으로 제거 할 수 있다는 점에서 유용 할 것입니다. 흥미 롭다, 나는 볼 것이다. – Spyros

관련 문제