问题在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
应该是一个数组。 改变一个属性的类型(鸭子打字可以)来回是一个坏主意,因为你可能会忘记当前的状态并且迟早会遇到错误。
为了遵循“关注点分离”,我建议仅在Office
对workers
进行全面管理,否则会过于混乱,从长远来看将难以维护。
我不是100%肯定你为什么不在这里得到错误,但是因为Office#工作者的最后一行是self.workers << worker,你正在添加在Office#workers中创建的新工作者(在第3行制作)方法),然后返回workers对象,然后使用在方法外创建的新worker重新调用#<<