2015-04-14 2 views
1

Я ссылаюсь к follwing статье paragaph «Pitfall # 1»: http://definingterms.com/2013/03/23/pitfalls-of-ruby-mixins/Понимание механизма прокси-класс в рубин подмешать в

У меня есть следующие настройки, немного изменила форму, используемую в статье:

module EmailReporter 
    def send_report 
     #Sending a report ... 
     puts self.class 
    end 
end 

class Person 
end 

class Employee < Person 
    include EmailReporter 
end 

Как я понимаю, когда я включаю EmailReporter в Employee, его методы не только вставить в него, но анонимный прокси-класс создан и введен в цепочке наследования выше Работника и под Person.

Когда я вызываю Employee.new.send_report, я не входит в сферу деятельности Employee, а входит в сферу действия прокси-класса. Таким образом, у меня не было бы доступа к константам или переменным класса Employee, но у меня был бы доступ к переменным экземпляра.

Вопросы:

  1. Если я бегу Employee.new.send_report, выход "Сотрудник", а не что-то вроде "Employee__proxy_class". Почему это? Не следует ли «я» ссылаться на класс прокси?

  2. В статье предлагается, чтобы метод делегатов класса прокси-сервера вызывал модуль EmailReport. Но, конечно, вы не можете просто вызвать методы экземпляра на нем. Итак, кому доверяет класс прокси-сервера?

Спасибо всем, кто пытается ответить на мой вопрос!

+0

само относится к приемнику, поэтому многие из методов в рубине работают. Возьмем, например, метод '# send'. '# send' определяется в' Object', но вы не хотите, чтобы 'Employee.send' выполнялся в контексте самого объекта и терял контекст' Employee'. включенные модули, в то время как они могут быть «классом включения», в сущности, вводят свои методы в класс, в который они были включены. Причина, по которой это делается на более высоком уровне, - это позволить вам переписать методы в самом классе. Все методы делегируются цепочкой наследования, если только 'method_missing' прерывает это. – engineersmnky

+0

А, спасибо. Что касается себя, конечно, вы правы, и я не знаю, почему я этого не понял. Значит, это означает графику в статье (http://definingterms.com/images/posts/mixins_d3.jpg), а также класс класса proxy вводит в заблуждение, потому что прокси-класс выше Employee не делегирует никому другому классу, но содержит сами методы. – thedudedude

+0

Я бы сказал, что это немного вводит в заблуждение. Я думаю, что причина, по которой он ссылался на это как прокси-сервер, заключается в том, что он может быть включен в любом месте, не соответствует единственному принципу наследования и разрывает инкапсуляцию. – engineersmnky

ответ

1

Я думаю, что ваша фундаментальная проблема заключается в понимании значения self. Часто полезно просто добавить код, который сообщает вам, что self находится в разных точках вашего кода. Давайте начнем с простого примера:

class Dad 
    def hi 
    puts "self in Dad#hi = #{self}" 
    end 
end 

class Son < Dad 
end 

son = Son.new 
    #=> #<Son:0x007fc1f2966b88> 
son.methods.include?(:hi) 
    #=> true 
son.hi 
    # self in Dad#hi = #<Son:0x007fc1f2966b88> 

Просто потому, что:

son.method(:hi).owner 
    #=> Dad 

не означает, что self изменяется, когда hi вызывается self. Теперь давайте включать подмешать:

module Helper 
    def hi 
    puts "self in Helper#hi = #{self}" 
    end 
end 

Son.include Helper 

son.hi 
    # self in Helper#hi = #<Son:0x007fc1f29551d0> 
son.method(:hi).owner 
    #=> Helper 

Я думаю, вы понимаете, почему Helper#hi был вызван здесь, а не Dad#hi.

Ответит ли это на ваш первый вопрос? Я не понимаю второй вопрос, но, возможно, вы сами можете ответить на него сейчас, когда просветили вас по адресу self. Если нет, уточните №2 (с редактированием на ваш вопрос).

+0

Спасибо! Это подтверждает ответ инженеры в комментарии моего сообщения. # 2 был о том, что меня путают, что автор писал о «прокси-классе» - я думал о прокси-шаблоне и в сочетании с графикой (defineterms.com/images/posts/mixins_d3.jpg), я думал, что прокси-класс будет делегировать к другому классу, чего нет. – thedudedude

Смежные вопросы