la, 2005-04-30 kello 00:14, Vincent Foley kirjoitti: > Hi everyone, > > I finished playing yet another game of Chrono Trigger the other day, > and I thought I would look at how I could implement a simple Character > system in Ruby. I have the following initialize method, but I would > like to be sure it's not extremely bad style: > > class Character > attr_accessor :strength, :magic, :defense, :magic_defense > > def initialize(args = {}) > args.each do |k, v| > instance_variable_set("@#{k}", v) if respond_to?(k) > end > > methods.grep(/\w=$/).each { |setter| > getter = setter[0..-2] > if send(getter).nil? > send(setter, 0) > end > } > end > end > > So, if I added a :critical_rate accessor, I wouldn't need to modify > anything else in the initialize method. Also, I don't want nil in any > attribute. Is this good style? Are there other (maybe better) ways to > accomplish this? Thank you. Hello, I've been using a pretty similar class for my config needs, maybe the biggest difference is that I'm using a default_config method to get the default values and to make it work properly with subclassing. I quite like the respond_to?-check you've got there, think I'll extend mine by raising a name error if the setter doesn't exist.. or just use a config block more often :| Anyhow, here's the class: class Configurable def initialize(config = {}, &optional_config_block) config = default_config.merge(config) config.each{|k,v| instance_variable_set("@#{k}", v)} optional_config_block.call(self) if block_given? end def default_config {} end end #subclassing: class Foo < Configurable attr_accessor :foo def default_config super.merge({ :foo => 10 }) end end Foo.new :foo => 5 Foo.new{|f| f.foo = 5 } class FooBar < Foo attr_accessor :bar def default_config super.merge({ :bar => 20 }) end end fb = FooBar.new fb.foo #=> 10 fb.bar #=> 20