Here's a function similar to attr_accessor, except it takes a block, which is used to validate assignments to the attribute, and substitute in a string value to be used as a key to the hash inside class_eval. It's just ugly having to use a hash to store the block. class_eval and friends should support saving parameters into global variables for the duration? Or is there an obvious way of doing this that I've missed? I removed some checking for simplicity. Clifford Heath. def validated_attr(*names, &block) begin Thread.critical = true $__VALIDATOR_BLOCK ||= {} while $__VALIDATOR_BLOCK.has_key?([r = (rand*16777216).to_i]); end $__VALIDATOR_BLOCK[r] = block ensure Thread.critical = false end names.each{|name| class_eval <<-END def #{name} @#{name} end def #{name}=(__val) if !$__VALIDATOR_BLOCK[#{r.to_s}.to_i].call(__val) throw "Invalid assignment of \#{__val.inspect} to #{name}" end @#{name} = __val end END } end class Foo validated_attr(:bar) {|v| v.kind_of?(Integer) && (0..14).include?(v)} end f = Foo.new begin f.bar = 2 # Ok rescue => e puts e.to_s end begin f.bar = 15 # Not ok rescue => e puts e.to_s end begin f.bar = "Hi there" # Not ok rescue => e puts e.to_s end