From: Daniel Schierbeck Date: 2006-07-06T23:54:06+09:00 Subject: Re: newbie Q: conditional object creation Paul Van Delst wrote: > I'm want to be able to create objects, but I want the object creation to > only proceed if the values passed to the init method are in a valid > list. E.g.: > > class MyObj > VALID_NAMES=['bananas','dog','water'] > attr_reader :name, :value > def initialize(name,value) > i=VALID_NAMES.index(name) > if i then > @name,@value=name,value > else > @name,@value=nil > end > end > end > > This sorta does what I want, but looks clunky, ugly and quite > un-ruby-ish. Is there a better way (idiom?) to achieve this sort of > thing? I.e. is there a way to make the init method not create even an > "empty" object (as happens above) based on the valid names list? class MyObj VALID_NAMES = %w{bananas dog water} # array of strings # go into the metaclass class << self alias_method :__new__, :new def new(name, value) raise unless VALID_NAMES.include? name __new__(name, value) end end def initialize(name, value) @name, @value = name, value end end This will raise an exception when MyObj.new is called with an invalid name. You should read up on metaclasses if you haven't already[1]. If you just want MyObj.new to return nil when supplied with an invalid argument, this will do the trick: def new(name, value) __new__(name, value) if VALID_NAMES.include? name end Cheers, Daniel [1] http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html