问题在ruby中支持双向语法

时间:2011-06-06 05:58:58

标签: ruby-on-rails ruby rubygems

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

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 <<(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

我可以做这样的事情

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 ??

实例

2 个答案:

答案 0 :(得分:1)

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

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应该是一个数组。改变一个属性的类型(鸭子打字可以)来回是一个坏主意,因为它可能会失去对当前状态的跟踪,你迟早会遇到错误。

要遵循“关注点分离”,我建议仅在workers中对Office进行整个管理,否则会过于混乱,并且在长期内难以维护跑。

答案 1 :(得分:0)

我不是100%肯定你为什么不在这里收到错误,但是因为Office#工作者的最后一行是self.workers&lt;&lt; worker,您正在添加在Office#workers中创建的新工作程序(在方法的第3行上创建),然后返回workers对象,然后获取#&lt;&lt;使用在方法

之外创建的新工作程序再次调用它