2011-09-09 3 views
1

Ruby 1.9에서 eval()을 사용하여 대화 형 방식으로 루비 코드 조각을 테스트하고 싶습니다. 오래 전 (Ruby 1.4)이 기능을 제공하는 인터넷에서 깔끔한 스크립트를 발견했습니다. 여기에 단순화 및 감소 버전 : 인해 eval()의 변경된 의미에 그러나 더 이상은 1.9에서,Ruby 1.9에서 eval()을 사용하여 Ruby 코드 조각 테스트

ruby> str = "a:b:c" 
"a:b:c" 
ruby> str.split /:/ 
["a", "b", "c"] 
ruby> 

이 스크립트는 루비 1.8까지 잘 작동 :

line = '' 
$stdout.sync = true 
print "ruby> " 
while true 
    input = gets 
    if input 
     line = input 
    else 
     break if line == '' 
    end 
    begin 
     print eval(line).inspect, "\n" 
    rescue ScriptError, StandardError 
     $! = 'exception raised' unless $! 
     print "ERROR: ", $!, "\n" 
    end 
    break if not input 
    line = '' 
    print "ruby> " 
end 

내가 좋아하는 뭔가를 할 수 있었다 . 이제 str과 같은 로컬 변수를 만들 수 없습니다.

ERROR: undefined local variable or method `str' for main:Object 

수정하는 방법 또는 우회 eval()의이 문제가 있습니까 대신 나는 다음과 같은 분명한 메시지가? 바인딩에 대해 읽었지만 여기에서 어떻게 바인딩할지 모르겠습니다.

물론 irb이지만 그 도구에서는 "abc#{var}def"과 같은 파운드 기호를 사용할 수 없습니다. 만약 내가 시도하면 전체 라인을 irb 주석.

+0

"abC# {var} def"는 irb에서 작동합니다. – Dogbert

답변

4

근무 코드 :

$stdout.sync = true 
while true 
    print "ruby> " 
    input = gets 
    break unless input 
    begin 
    p eval(input, TOPLEVEL_BINDING) 
    rescue ScriptError, StandardError 
    puts "ERROR: #{$! || "exception raised"}" 
    end 
end 

나는 깨끗하게 만들기 위해 코드에서 많은 일을 변경,하지만 포인트는 eval의 범위이다. begin 블록 내부에서 실행되었습니다. eval에 의해 정의 된 모든 로컬 변수는 begin 블록 내부에서 생성되었으며 각 반복 후에 begin이 끝날 때 파괴되었습니다. 상수 TOPLEVEL_BINDING은 최상위 수준 (모든 것 외부)의 범위를 반환합니다. eval은 프로그램이 끝날 때까지 코드가 손상되지 않도록 코드를 실행합니다. binding 메서드를 사용하여 어떤 장소의 범위를 가져 와서 eval의 두 번째 인수로 보낼 수도 있습니다.

def get_a_binding 
    x = 42 
    return binding 
end 

x = 50 
scope = get_a_binding 
eval("print x", scope) #=> prints 42 
관련 문제