2014-04-15 3 views
1

initialize 메서드가 호출 된 후 실행되는 루비 코드를 작성하고 싶습니다. 이 코드는 클래스 또는 모듈에있을 수 있습니다. 어떻게 쓸 수 있니?initialize 메서드 후 메서드 실행

class Base 
    def after_init 
    puts "after init" 
    end 

class A < Base # Option 1, use a class 
end 

class B < Base 
    def initialize 
    puts "in init" 
    end 
end 

module MyMod 
    def after_init 
    puts "after init" 
    end 
end 

class C 
    include Module 
end 

$> A.new 
=> "after init" 
$> B.new 
=> "in init" 
=> "after init" 
$> C.new 
=> "after init" 

내가 분명히하고 싶은 않는다 super에 명시 적으로 호출 할 수 있습니다 : 여기

내가 원하는 무엇의 예입니다. 이것을 할 수있는 방법이 있습니까? 루비의 반사 능력이 많은지 신경 쓰지 않습니다. 감사!

+0

: 모듈로? –

+0

사용자가 사용할 라이브러리를 작성 중입니다. 사용자는 클래스를 확장하거나 모듈을 포함시킵니다. 추가 된 동작은 완전히 초기화되는 사용자 클래스의 상태에 따라 다릅니다. 사용자 클래스의 끝에서'super '를 호출해야한다는 요구 사항이 너무 엄격해서 버그가 발생하기 쉽습니다. – Max

답변

4
class Base 
    def after_init 
    puts "Base#after_init" 
    end 

    def self.inherited(klass) 
    class << klass 
     alias_method :__new, :new 
     def new(*args) 
     e = __new(*args) 
     e.after_init 
     e 
     end 
    end 
    end 
end 

module MyMod 
    def after_init 
    puts "MyMod#after_init" 
    end 
    def self.included(klass) 
    class << klass 
     alias_method :__new, :new 
     def new(*args) 
     e = __new(*args) 
     e.after_init 
     e 
     end 
    end 
    end 
end 

class A < Base 
end 

class B < Base 
    def initialize 
    puts "B#initialize" 
    end 
end 

class C 
    include MyMod 
    def initialize 
    puts "C#initialize" 
    end 
end 

A.new 
B.new 
C.new 
2

다음은 상속 할 수있는 예를 들어 클래스의 : 나는 new를 재정 의하여 일어날 수있는 모든 것을 통해 생각

class MyClass 
    class << self 
    alias_method :_new, :new 

    def new 
     _new.tap do |instance| 
     instance.send(:after_init) 
     end 
    end 

    end 

    private 

    def after_init 
    puts 'after_init' 
    end 
end 

, 그러나 이것은 당신이 시작하는 데 충분합니다.

편집 : 당신은`super`에 대해이 무엇

module MyMixin 
    def self.included(base) 
    class << base 
     alias_method :_new, :new 

     define_method :new do 
     _new.tap do |instance| 
      instance.send(:after_init) 
     end 
     end 
    end 
    end 

    def after_init 
    puts 'hello' 
    end 
end 

class MyClass 
    include MyMixin 
end 
+0

정말 고마워. 모듈에서이를 수행 할 수있는 방법이 있습니까? 비슷한 것을 시도했지만 클래스에'new '메소드가 없다는 에러가 발생했습니다. – Max

+0

예, 수정 된 답변을 참조하십시오. –

+0

@ ArieShaw의 대답도 살펴보아야한다. 특히 그가 'new'에 대해'* args'를 포함하고있는 곳은 잊어 버렸다. –