2013-05-29 2 views
0

Я пытаюсь высушить декораторы в проекте Rails.Почему это классовое наследование вызывает бесконечную рекурсию

По сути, я хочу делегировать любые отсутствующие методы объекту ресурса (или классу ресурса объекта).

Вот упрощенный пример

# Decorator base class 
class Decorator 
    attr_accessor :resource 

    private 

    def method_missing(name, *args, &block) 
     self.resource.send(name, *args, &block) 
    end 

    # infinite recursion happens here 
    def self.method_missing(name, *args, &block) 
     self.resource.class.send(name, *args, &block) 
    end 

end 

# Decorator class that will be used 
class UserCreator < Decorator 
    attr_reader :user 
    def initialize(params) 
     @user = User.new(params[:user]) 
     self.resource = @user 
    end 

    def save 
     # do special stuff with user object 
     if @user.save 
      # perhaps do some more stuff after the save 
      true 
     else 
      # perhaps handle the error here 
      false 
     end 
    end 

end 

# A simple controller example 
class SomeController < ApplicationController 
    respond_to :json 

    def create 
     @user = UserCreator.new(params) 

     if @user.save 
      render :json => @user 
     else 
      render :json => @user.errors 
     end 
    end 
end 

Тем не менее, в классе Decorator бесконечной рекурсии происходит в методе self.method_missing класс (Singleton). В этом методе проходит resource как аргумент name.

Я пытаюсь обвести голову вокруг потока управления тем, что здесь происходит. Метод resource существует в базе Decorator класса через attr_accessor, поэтому я думал, что в подклассе UserCreator также есть этот метод. Поэтому я не уверен, почему он считает, что resource является отсутствующим методом. Если я избавлюсь от суперкласса Decorator и просто реализую method_missing s в классе UserCreator, все работает так, как ожидалось.

Любая помощь в реализации этого базового класса для работы в соответствии с ожиданиями очень ценится, поэтому мне не нужно реализовывать те же методы method_missing в каждом декораторе.

+0

К сожалению. Да, опечатка. Хороший глаз. –

ответ

2

Второй способ method_missing - метод класса. Поэтому внутри этого метода self относится к классу, а не к экземпляру.

Однако метод пытается получить доступ к self.resource, который является атрибутом экземпляра, а не класса.

Поскольку Decorator класс не имеет resource атрибут, method_missing вызывается снова ... и снова ... и снова ...

Я пытаюсь обернуть мою голову вокруг потока управления, что происходит Здесь. Способ ресурсов существует в базовом классе декоратор через attr_accessor,

Он существует в случаях класса декоратор, но не в самом классе.

так что я думал, что подкласс UserCreator также имеет этот метод.

В экземпляры из UserCreator подкласса имеют, но не подкласс сам.

+0

Очень хорошо объяснено. Спасибо. –

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