From: Ilmari Heikkinen Date: 2005-05-10T00:43:40+09:00 Subject: Re: An idiom I like... modifiable defaults On 9.5.2005, at 17:42, Hal Fulton wrote: > Just thought I'd share a little concept that I find > useful. Your comments are welcome. > > Sometimes objects are created with certain defaults. > One way to override them is with default values in > the constructor (and often corresponding writer methods). > > But sometimes I "don't like" the default and want to > change it (for this program/session). > > Often I use class-level accessors for that purpose. > > Here's a contrived example... > > > Cheers, > Hal > Hi, I quite like this, but wonder if it works with inheritance? On a related note, it seems a lot of people (you, me, Ara Howard, probably many others) are coming up with these configuration idioms, maybe we could find a way that fulfills most needs (and perhaps even try to get it into ruby core)? Here's a quick list of features for discussion, feel free to add your own: - named arguments (ie. hash argument way) - auto-assigning configuration vars to instance variables - works with inheritance (this is probably the most difficult -- and useful -- one) - auto-generated accessors - configuration by block - maybe some way to co-operate with the regular positional params Would look something like this in use: class Image include TheAutoConfigModule config_accessor{ name # defaults to nil width = 100 height = 100 depth = 32 } def bytes @width * @height * @depth / 8 end end class BWImage < Image config_accessor{ depth = 8 } end i = Image.new(:height => 200, :depth => 16) i.width == 100 and i.height == 200 and i.depth == 16 #=> true i.name #=> nil i.bytes #=> 40000 bwi = BWImage.new( 'holiday shots', 10, 10 ) bwi.width == 10 and bwi.height == 10 and bwi.depth == 8 #=> true bwi.name #=> 'holiday shots' bwi.bytes #=> 100 Image.config #=> {:name => nil, :width => 100, :height => 100, :depth => 32} BWImage.config.height = 200 BWImage.config #=> {:name => nil, :width => 100, :height => 200, :depth => 8} Thoughts? Cheers, Ilmari > > class Text > > class << self > attr_accessor :color > Text.color = "black" > end > > attr_accessor :color > > def initialize(txt, color="black") > # Hint: You can improve this further by saying > # def initialize(txt, color=Text.color) > puts "#{color} text..." > end > end > > > # The old way... > > a = Text.new("some") # black > b = Text.new("random","blue") # blue > c = Text.new("text") # black > c.color = "blue" # but now it's blue > > # The new way... > > Text.color = "blue" > > e = Text.new("Ruby is cool") # blue > f = Text.new("as dry ice") # blue >