views:

81

answers:

3

Guys for wc, a rubygem I'm writing and that is useful for counting word occurrences in a text, I choose to put 3 parameters in class constructor.

The code is working, but I want to refactor it for niceness. In your experience, it's easier to read/mantain/use as API a class with a constructor with no params and a lot of setters/getters method or a code like this one, with all the params in the constructor?

TIA

Paolo

def initialize(filename, words, hide_list)

  if ! filename.nil?
    @filename = filename
    @occurrences = read
  else
    @filename = STDIN
    @occurrences = feed
  end

  @hide_list = hide_list
  @sorted = Array(occurrences).sort { |one, two| -(one[1] <=> two[1]) }
  @words = words

end
A: 

I dont know how it is in Ruby, but in other languages you usually put those arguments in the constructor signature that are needed to initialize the object into a valid state. All other state can be set through setters.

Gordon
In this case, parameters are options to customize class behavior when firing its task.There aren't required to object initialization.
thesp0nge
@thesp0nge if Ruby supports optional arguments, then you could make those optional arguments to reflect their optionality. Or add setters for the options. You should also consider what the others said about mutability.
Gordon
+1  A: 

In my experience I can tell that the very reason for allowing constructor parameters in most languages, apart from the fact of increasing the easiness in class instantiation, is to make it easy to use the API.

Favoring constructor, over getter/setter instantiation, also helps immutability, that is, creating an object thorough its constructor, and not letting anyone modify its properties later on.

StudiousJoseph
+1  A: 

You could do it the rails way, where options are given in a hash:

def initialize(filename = nil, options = {})
  @hide_list = options[:hide_list]
  @words = options[:words]

  if filename
    @filename = filename
    @occurrences = read
  else
    @filename = STDIN
    @occurrences = feed
  end

  @sorted = Array(occurrences).sort { |one, two| -(one[1] <=> two[1]) }

end

Then you can call it like this:

WC.new "file.txt", :hide_list => %w(a the to), :words => %w(some words here)

or this:

wc = WC.new
wc.hide_list = %w(a the is)
wc.words = %w(some words here)
mckeed
Mate this piece of code looks really good
thesp0nge