问题在ruby中支持双向语法

我有一种情况需要调用这样的东西:

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 

工人阶级

 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 !@office_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 < {: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 

我可以做这样的事情

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

但我需要做同样的事情,如上所述。 在此之前,我需要更改Office的初始化方法以启动工作者实例的def <<(worker)方法。

 class Office ... def initialize @workers = Worker.new @workers.office_id = self.id end office = Office.new() new_worker = Worker.new() office.workers << new_worker 

现在的问题是,后面的实现创建了2个worker的实例?

我不完全确定,但我想你想要这个:

 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 

结束

这样你就可以完全摆脱Worker#<< ,你也应该删除这一行

 office.workers = self 

Worker#initialize因为office.workers应该是一个数组。 改变一个属性的类型(鸭子打字可以)来回是一个坏主意,因为你可能会忘记当前的状态并且迟早会遇到错误。

为了遵循“关注点分离”,我建议仅在Officeworkers进行全面管理,否则会过于混乱,从长远来看将难以维护。

我不是100%肯定你为什么不在这里得到错误,但是因为Office#工作者的最后一行是self.workers << worker,你正在添加在Office#workers中创建的新工作者(在第3行制作)方法),然后返回workers对象,然后使用在方法外创建的新worker重新调用#<<