2011-06-06 9 views
9

Tengo una situación donde tengo que llamar a algo como esto:problema que soporta dos sintaxis forma en rubí

class Office 

    attr_accessor :workers, :id 

    def initialize 
    @workers = [] 
    end 

    def workers worker 
    type = worker.type 
    resp = Worker.post("/office/#{@id}/workers.json", :worker => {:type => type}) 
    worker = Worker.new() 
    resp.to_hash.each_pair do |k,v| 
     worker.send("#{k}=",v) if worker.respond_to?(k) 
    end 
    self.workers << worker 
    end 

end 

clase Trabajador

class Worker 
    attr_accessor :office_id, :type, :id 

    def initialize(options={}) 
    @office_id = options[:office].nil? ? nil : options[:office].id 
    @type = options[:type].nil? ? nil : options[:type].camelize 
    if [email protected]_id.nil? 
     resp = self.class.post("/office/#{@office_id}/workers.json", :worker => {:type => @type}) 
     @id = resp.id 
     office = options[:office] 
     office.workers = self 
    end 
    end 

    def <<(worker) 
    if worker 
     type = worker.type 
     resp = Worker.post("/office/#{office_id}/workers.json", :worker => {:type => type}) 
     debugger 
     @id = resp.id 
     resp.to_hash.each_pair do |k,v| 
     self.send("#{k}=",v) if self.respond_to?(k) 
     end 
     debugger 
     return self 
    end 
    end 

puedo hacer algo como esto muy bien

office = Office.new() 
new_worker = Worker.new() 
office.workers new_worker 

Pero tengo que hacer lo mismo que he hecho anteriormente como el siguiente. Antes de eso, necesito cambiar el método de inicialización de Office para iniciar el método def <<(worker) de la instancia de trabajador.

class Office 
    ... 
    def initialize 
    @workers = Worker.new 
    @workers.office_id = self.id 
    end 


office = Office.new() 
new_worker = Worker.new() 
office.workers << new_worker 

¿Ahora el problema es que la implementación posterior crea 2 instancias del trabajador?

+0

¿Qué hace el código? – Zabba

+3

@zabba, agrega un nuevo objeto worker dentro de los atributos de worker del objeto office y el atributo worker es una matriz. –

+1

¿Cambió más código que solo eso? Tal como está, office.workers << new_worker debería ser un ArgumentError, ya que office.workers es un método que toma 1 parámetro. –

Respuesta

0

No estoy 100% seguro de por qué no está obteniendo un error aquí, pero como Office # workers last line es self.workers < < trabajador, está agregando el nuevo trabajador creado en Office # workers (hecho en la tercera línea del método), y luego devolver el objeto de los trabajadores, que luego obtiene # < < llamado nuevamente con el nuevo trabajador creado fuera del método

+2

sí, es por eso que se estropeó para implementar eso ... así que cualquier idea de cómo puedo implementar el método # << cuando llamo a 'office.workers << new_worker' como lo hice en' office.workers new_worker' –

+0

Elegiría un nombre diferente para el atributo para que pueda hacer 'office.workers new_worker' y' office.new_worker_name << new_worker'.Idealmente, habría elegido 'office.add_worker new_worker' y' office.workers << new_worker', pero parece que tiene un código heredado para admitir, por lo que no quiere cambiar las llamadas anteriores. (Sé que esto no es lo que pediste, pero así es como lo haría. Si explicaras mejor el escenario, podría darte una respuesta diferente) –

+2

Solo quiero el mismo funcionamiento para el último método ya que tengo hecho en el anterior y con el mismo nombre. cuando llamo a 'office.workers << new_worker' simplemente llama al atributo getter/setter predeterminado de workers. –

1

No estoy del todo seguro, pero supongo que usted ' d gustaría tener esto:

class Office 

    attr_accessor :workers, :id 

    def initialize 
    @workers = [] 
    end 

    alias_method :workers, :return_worker_array 

    def workers worker 
    unless worker 
     return_worker_array 
    else 
     type = worker.type 
     resp = Worker.post("/office/#{@id}/workers.json", :worker => {:type => type}) 
     worker = Worker.new() 
     resp.to_hash.each_pair do |k,v| 
     worker.send("#{k}=",v) if worker.respond_to?(k) 
     return_worker_array << worker 
    end 
end 

final

De esta manera usted puede deshacerse de Worker#<< por completo y también se debe quitar la línea

office.workers = self 

en Worker#initialize desde office.workers se supone que es una matriz. Es una mala idea cambiar el tipo de un atributo (el tipado de pato estaría bien) de ida y vuelta porque es probable que pierda la noción del estado actual y tarde o temprano se encontrará con errores.

Para seguir "Separación de preocupaciones", recomendaría hacer toda la administración de workers únicamente en Office, de lo contrario, se vuelve demasiado confuso demasiado rápido y será mucho más difícil de mantener a largo plazo.