2014-11-22 13 views
0

일부 메타 프로그래밍 개념을 사용하고 있으며 내가하고 싶은 일이 단순히 가능한지 궁금합니다.오브젝트 컨텍스트에서 파일을로드하는 방법

//test_events.rb 
event 'monthly events are suspiciously high' do 
    true 
end 

이벤트에 대한 간단한 DLS가있다

및 이벤트가 true를 돌려주는 경우 스크립트가 외치다한다, 나는 방법 이벤트 글로벌 네임 스페이스를 오염없이이 작업을 수행하려고하고 인스턴스 변수. 그래서 나는이 같은 시도 : 나는 MyClass에의 맥락에서로드하고자하는 각 * _events.rb 파일 그래서

Dir.glob('*_events.rb').each do |file| 

    MyClass = Class.new do 
    define_method :event do |name, &block| 
     @events[name] = block 
    end 
    end 

    env = MyClass.new 

    env.instance_eval{@events = {}} 

    env.instance_eval{load(file)} 

end 

을 (내가 Dir.glob 번호의 두번째 루프 각 이미 불평 것이라는 점을 알고있다 정의 된 const - 지금은 중요하지 않음). 내가

undefined method `event' for main:Object (NoMethodError) 

을 할 수있는 방법이 있나요를 얻을 수 있기 때문에

문제는 개체 컨텍스트에서 실행됩니다 test_events.rb에 env.instance_eval{load(file)} 코드인가? (나는 1.9.3 지금 시도하지만 버전 업을 변경하면 그냥 운동이기 때문에 문제가되지 않는다)

+0

: 당신이처럼 뭔가를 전달하는 문자열로 파일 내용을 읽을 필요) 최상위 레벨에서 파일 : http://robots.thoughtbot.com/writing-a-domain-specific-language-in-ruby –

+0

감사합니다. 정말 재미 있습니다. 그럼에도 불구하고 나는 내 질문에 대한 답을 찾지 못했습니다. 문제는 다음과 같이 작동하는 DSL을 만드는 것입니다.'Redflag.register do 이벤트 '월별 이벤트가 의심 스러울 정도로 높습니다. do true end end 이것은 매우 쉽습니다. 하지만 내 질문을 바꿔 보자 : 모든 개체 인스턴스의 컨텍스트에서 Kernel # load를 호출하는 방법. 내 모든 시도에서 항상 최상위 오브젝트 Object 컨텍스트에서 호출되는 것처럼 보입니다. 가능한가? – meta

+1

AFAIK 아니요, 'load'은 컨텍스트에 민감하지 않습니다. 코드를 전역 범위에로드합니다. –

답변

2

instance_eval 대신 블록의 인수로 String 걸릴 수 있습니다, 그래서보다는 당신이 제안으로 load합니다 (로드됩니다 당신은 루비에서 사용자 지정 DSL을 만드는 방법에 대한 연습이 블로그 게시물에서 볼 수도 있습니다

env.instance_eval(File.read(file))