On Tue, Nov 1, 2011 at 11:13 AM, Michael Kohl <citizen428 / gmail.com> wrote:
> On Tue, Nov 1, 2011 at 3:14 AM, Reginald Tan <redge.tan / gmail.com> wrote:
>> I have a class that uses hash as its internal store. What's a good way
>> to communicate the interface of my methods.

Document them.

> Do you need to leak this implementation detail? You could make
> add_content a two argument method and changing it like this:
>
> def add_content(k, v)
>     > end

I don't see how changing the argument count of #add_content has
anything to do with "leaking implementation detail".  It's perfectly
OK to use #add_content with a single Hash argument - regardless of
internal representation.  I think you are mixing two unrelated things
here.

The only place where leaking actually comes into play is return
values: both methods leak the internal Hash.  But that can be easily
avoided by returning self and using #dup.

Whether it is wise to use a single Hash argument when the intention is
actually to just add a pair (of what btw?) is another question.  So,
to remedy this one could do

class Book
  def initialize
    @structure = {}
  end

  # Add another chapter with title.
  def add_content(chapter, title)
    raise "Wrong arguments" unless Integer === chapter && String === title
    @structure[chapter] = title.dup.freeze
    self
  end

  # Get the (ordered) list of chapter numbers and titles.
  def contents
    @structure.dup
    # or: @structure.sort_by {|chapter, title| chapter}
  end
end

Kind regards

robert

-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/