2009-06-17 3 views
0

루비에서 모듈 재정의?

이 코드는 vendor/{engine}/app/helpers/application_helper.rb 있습니다 :

module ApplicationHelper 
    def application_title() 
    "Foo" 
    end 

    def other_method() 
    # ... 
    end 
end 

그리고 app/helpers/application_helper.rb :

module ApplicationHelper 
    def application_title() 
    "Bar" 
    end 
end 

내 응용 프로그램에서 application_title() 호출 할 때 예상대로 "막대"얻을 수 있지만 내 응용 프로그램은 other_method() 볼 수 없습니다. 이 문제를 해결하기 위해 ApplicationHelper을 어떻게 수정합니까?

+0

흠 ... 왜 그런지 모르겠다. 첫 번째 ApplicationHelper가 프로젝트에 전혀 포함되지 않았습니까? 'application_title'을 제거하면 "Foo"가 생깁니 까? –

+0

. 도우미가 앱에 실제로 포함되어 있는지 확인 하시겠습니까? – cpjolicoeur

+0

application_title() 메서드를 삭제하면 application_title()이 정의되지 않은 오류가 발생합니다. 그러나 모듈을 완전히 삭제하면 "Foo"가 표시됩니다. –

답변

0

내 생각 엔 문제는 엔진의 도우미가 주 앱의 엔진을 우회 할 것으로 예상한다는 것입니다. 나는이에 가져되지 않은 엔진 플러그인이 아니라 레일 2.3이 기능에서 근무 믿습니다.에서

http://rails-engines.org/news/2009/02/02/engines-in-rails-2-3/

코드 ' 의 작업을 수행하려고 시도하지 않습니다

레일 2.3 혼합 코드 믹싱 '엔진 플러그인 않습니다. 하지 알고있는 당신의 그것들을 위해,이 응용 프로그램이 당신의 응용 프로그램에 플러그인에서 전체 파일을 복사 할 필요없이 컨트롤러 또는 도우미에서 하나의 메소드를 오버라이드 (override) 할 수있는 기능 입니다.

내가 확실히 말할 수는 없지만, 나는이 기능은 지금까지 레일 자체에 그것을 만들 것이며, 솔직히 말해서, 나는 그 아마 좋은 일이라고 생각 을 의심한다. 코드 믹싱 메커니즘이 인데 반해 메서드 구현을 재정의하는 다른 방법이 있습니다.보다 일반적인 방법은 루비시 (Rubyish)이며 마술은 덜합니다.나는 곧 몇 가지 예제를 시도하고 게시 할 것이다.

희망이 도움이됩니다.

+0

엔진 작동 방법에 대한 예는 http://agilewebdevelopment.com/plugins/datebocksengine을 참조하십시오. –

+0

구체적으로 5 단계는 엔진에서 도우미를 프로젝트 도우미로 포함시키는 것을 보여줍니다. –

+0

D' oh. 글쎄, 그건 좀 어색해. 이 기능을 사용할 수 있기를 정말로 바랬습니다. 사물을 더 똑똑하게 처리 할 수 ​​있습니까? –

0

필자는 이것이 레일스의 문제라고 말할 수는 없지만 멀리 떨어져있는 것은 아닙니다. Rails 앱의 경우 끝에있는 "수정"이 쉽게 적용되지 않을 수 있습니다.

첫째, 디렉토리 목록 :

> ls -R 
.: 
bar_then_foo.rb bar_then_foo2.rb foo_then_bar.rb lib_foo lib_fubar 

./lib_foo: 
helper.rb 

./lib_fubar: 
helper.rb 

도우미 모듈 :

> cat lib_foo/helper.rb 
module Helper 
    def foo 
    puts "foo" 
    end 

    def bar 
    puts "bar" 
    end 
end 

> cat lib_fubar/helper.rb 
module Helper 
    def foo 
    puts "foo-bar" 
    end 
end 

루비 코드 :

> cat bar_then_foo.rb 
$LOAD_PATH.unshift File.dirname(__FILE__) + '/lib_fubar' 
$LOAD_PATH.unshift File.dirname(__FILE__) + '/lib_foo' 

require 'helper' 

class FoobieDoo 
    include Helper 
end 

f = FoobieDoo.new 
f.foo 
f.bar 

> cat foo_then_bar.rb 
$LOAD_PATH.unshift File.dirname(__FILE__) + '/lib_foo' 
$LOAD_PATH.unshift File.dirname(__FILE__) + '/lib_fubar' 

require 'helper' 

class FoobieDoo 
    include Helper 
end 

f = FoobieDoo.new 
f.foo 
f.bar 

그리고 일부 출력 :

> ruby bar_then_foo.rb 
foo 
bar 

> ruby foo_then_bar.rb 
foo-bar 
foo_then_bar.rb:12: undefined method 'bar' for #<FoobieDoo:0x1042e93c> (NoMethodError) 

그래서 Ruby는 끝에 $ LOAD_PATH를 검색하고 일치하는 항목을 찾으면 바로 중지합니다.

> cat bar_then_foo2.rb 
$LOAD_PATH.unshift File.dirname(__FILE__) + '/lib_fubar' 
$LOAD_PATH.unshift File.dirname(__FILE__) + '/lib_foo' 

require 'helper' 
load "lib_fubar/helper.rb" 

class FoobieDoo 
    include Helper 
end 

f = FoobieDoo.new 
f.foo 
f.bar 

> ruby bar_then_foo2.rb 
foo-bar 
bar 

원하는 결과 :

는의 다른 것을 해보자?

아마 app/helpers/application_helper.rb을 수정하여 LOAD_PATH에서 다른 application_helper.rb 파일을 검색하고로드 할 수 있습니까?