From: Phrogz Date: 2006-09-03T03:55:30+09:00 Subject: Re: Class behaviour Geoff Barnes wrote: > foo = Klass.new > foo.legal_values = (4..10) > > foo.value = 5 # OK > foo.value = 11 # ERROR - out of bounds, raise exception or something Do you want the legal values to be different per instance, or set for the whole class? Here are two options: class Klass class << self attr_accessor :legal_values end attr_reader :value def value=( new_value ) if value_range = self.class.legal_values raise "Out of Range" unless value_range.include?( new_value ) end @value = new_value end end foo = Klass.new bar = Klass.new Klass.legal_values = 4..10 foo.value = 8 puts foo.value #=> 8 bar.value = 17 #=> RuntimeError: Out of Range class Klass attr_accessor :legal_values attr_reader :value def value=( new_value ) if @legal_values raise "Out of Range" unless @legal_values.include?( new_value ) end @value = new_value end def legal_values=( new_range ) raise "Value outside Range" if @value && !new_range.include?( value ) @legal_values = new_range end end foo = Klass.new foo.legal_values = 4..10 foo.value = 8 puts foo.value #=> 8 bar = Klass.new bar.value = 200 puts bar.value #=> 200 bar.legal_values = 1..10 #=> RuntimeError: Value outside Range > Also, do I have to have an explicit method for the 'value', or can it > operate like a "builtin" class, like this : > > foo = Klass.new > foo.legal_values = (4..10) > > foo = 5 # OK > foo = 11 # ERROR - out of bounds, raise exception or something No, you can't do this - there is no assignment method (=) that you can override to do something different. "foo = 5" will always change the local variable 'foo' to point to a Fixnum of 5.