2015-12-16 9 views
3

Я хотел бы предложить некоторые усовершенствования DSL. Я могу получить уточнения, работающие с этим примером:Уточнения Ruby с экземпляром_exal

module ArrayExtras 
    refine Array do 
    def speak 
     puts 'array!' 
    end 
    end 
end 

module MyUniverse 
    using ArrayExtras 
    class Thing 
    def initialize 
     [1].speak 
    end 
    end 
end 
MyUniverse::Thing.new 

Это печатает «массив!». просто хорошо. Но как только я представлю instance_eval, метод не может быть найден:

module MyUniverse 
    using ArrayExtras 
    class DSL 
    def initialize(&block) 
     instance_eval(&block) 
    end 
    end 
end 

MyUniverse::DSL.new do 
    [1].speak 
end 

Я получаю undefined method говорить»для [1]: Array (NoMethodError)`

Есть ли способ, чтобы получить уточнения, работающие в экземпляр_eval?

ответ

2

Уточнения лексически ограничены. Вы активируете Уточнение в неправильном лексическом контексте. Вам необходимо активировать его, когда вы вызываете уточненный метод:

module ArrayExtras 
    refine Array do 
    def speak 
     puts 'array!' 
    end 
    end 
end 

module MyUniverse 
    class DSL 
    def initialize(&block) 
     instance_eval(&block) 
    end 
    end 
end 

using ArrayExtras 

MyUniverse::DSL.new do 
    [1].speak 
end 
# array! 
+0

А, получилось. Благодаря! – Andy

0

Если вы хотите улучшить рубиновый сердечник BaseObject, вам необходимо изменить его, как указано ниже.

module ArrayExtras 
    refine ::Array do 
    def speak 
     puts 'array!' 
    end 
    end 
end 

Он будет найден в классе высшего уровня.