I have a situation where i need to call something like this :
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
Worker class
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
I can do something like this very well
office = Office.new()
new_worker = Worker.new()
office.workers new_worker
But i need to do same what i have done above like the following. Before that, i need to change the initialize method of Office to fire up the def <<(worker) method of the worker instance.
class Office
  ...
  def initialize
    @workers = Worker.new
    @workers.office_id = self.id
  end
office = Office.new()
new_worker = Worker.new()
office.workers << new_worker
Now the problem is, the later implementation creates 2 instances of the worker??
Ruby does not support method overloading Method overloading is a feature of statically typed language in which binding of methods takes place during compile time. But Ruby being a dynamically typed language, it does not support static binding at all.
If you are eager to know how to use an OR condition in a Ruby switch case: So, in a case statement, a , is the equivalent of || in an if statement. See "How A Ruby Case Statement Works And What You Can Do With It".
|| has a higher precedence than or . So, in between the two you have other operators including ternary ( ? : ) and assignment ( = ) so which one you choose can affect the outcome of statements. Here's a ruby operator precedence table.
The || operator returns the Boolean OR of its operands. It returns a true value if either of its operands is a true value. If both operands are false values, then it returns a false value. Like && , the || operator ignores its righthand operand if its value has no impact on the value of the operation.
I'm not entirely sure, but I suppose you'd like to have this:
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
end
This way you can get rid of Worker#<< entirely and you should also remove the line 
office.workers = self
in Worker#initialize since office.workers is supposed to be an array. It's a bad idea to change the type of an attribute (duck-typing would be OK) back and forth because it's likely you lose track of the current state and you will run into errors sooner or later.
To follow "Separation of Concerns", I would recommend to do the entire management of workers solely in Office, otherwise it gets too confusing too quickly and will be much harder to maintain on the long run. 
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With