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.