Gavin Sinclair <gsinclair / soyabean.com.au> wrote in message news:<701387602747.20041021030313 / soyabean.com.au>...
> On Wednesday, October 20, 2004, 11:36:59 PM, rdlugosz wrote:
> 
> > Another option (which I'm betting won't be popular here...)
> > would be to have a separate RectangleBuilder class that will make Rectangles
> > for you.  You could have multiple methods here that would take reasonable
> > parameter sets based on their name.
> 
> The last serious Ruby project I worked on used a similar approach.  It
> was constructing something serious.  Can't remember what; let's use
> Rectangles.
> 

Gavin's approach is the one I like best.
Putting the logic of creation in another class is also a good idea
(that way you could enforce what parameters need to be defined or do
some more esoteric things if need arises).
Here's more fleshed out code, which I did just to think about it a
tad:

class Rectangle
  def initialize
    @p = Parameters.new
    yield @p if block_given?
  end

  def method_missing(*args)
    @p.send(*args)
  end
end

class Rectangle::Parameters
  attr_accessor :x, :y, :w, :h
  
  def initialize
    @x = @y = @w = @h = 0
  end
end


a = Rectangle.new { |p|
  p.x = 20
  p.y = 10
  p.w = 5
  p.h = 8
}

b = Rectangle.new

puts "Custom  rect: #{a.x} #{a.y}"
puts "Default rect: #{b.x} #{b.y}"


There's just two minor issues with such code.  One is that each
access/setting of a value is now going thru an added level of
indirection, so you do pay a small speed penalty for doing it this
way.  Having a factory method and a flat rectangle class instead
avoids this issue.

Another minor issue is that in case of a typo ( say, above, you use
a.width = 20, instead of a.w = 20, the NoMethodError may be a tad
confusing as it exposes the innards of your code in reporting errors
about the presumably hidden parameter class ).

However, where this approach is of not much use is on some method
invocation that requires a long list of optional parameters.  Creating
a new object and filling its data just for calling an instance's
method still feels too much C like and awkward.
That's still one thing where named parameters built into the language
seem like a good idea and one thing that I do miss from python.