0

In my gem I have a class called Client that I want to operate like this:

client = Client.new
client.content_type('pages').content_type

That means I want to set a property and then expect to immediately get it back in the same chain. This is what I have so far:

class Client
  attr_reader :content_type

  def initialize(options = {})
    @options = options
  end

  def content_type
    @content_type
  end

  def content_type(type_id)
    @content_type = type_id
    self
  end
end

Now when I try to run client.content_type('pages').content_type I get:

wrong number of arguments (given 0, expected 1) (ArgumentError)
    from chaining.rb:16:in `<main>'

What am I doing wrong? How do I write this correctly?

Amit Erandole
  • 11,995
  • 23
  • 65
  • 103

1 Answers1

1

The names of your methods are conflicting. The second method is overriding the first. Either use different names or consolidate to do both like:

class Client
  attr_reader :content_type

  def initialize(options = {})
    @options = options
  end

  def content_type(type_id = nil)
    if type_id
      @content_type = type_id
      self
    else
      @content_type
    end
  end
end

Btw, this code stinks because the returned values for this are of different type depending on how it's called. You shouldn't do it unless you have a good reason to.

Melvin Ram
  • 21
  • 2
  • Could you perhaps help me with improving the code design? What would a better design look like? – Amit Erandole Dec 17 '16 at 07:40
  • 1
    @Amit I suggest that `content_type` should be `attr_accessor` of your class, so you could do `client.content_type = "pages"` or `client.content_type # output "pages"`. – kengho Dec 17 '16 at 17:06