# Add a Module#attr\_validator method

**URL:** <https://www.ruby-forum.com/t/add-a-module-attr-validator-method/56608>\
**Category:** Ruby\
**Created:** [April 1, 2006, 5:54pm UTC](https://www.ruby-forum.com/t/add-a-module-attr-validator-method/56608 "2006-04-01T17:54:31Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![dasch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dasch](https://www.ruby-forum.com/u/dasch)\
**Post date:** [April 1, 2006, 5:54pm UTC](https://www.ruby-forum.com/t/add-a-module-attr-validator-method/56608/1 "2006-04-01T17:54:31Z")

</div>

I couldn’t find a Facets mailing list, and I know the developers use  
this list, so therefore I send my proposal here.

I’d like to see the addition of an attribute validator, i.e. a setter  
that checks to see if a block returns true when called with the new  
value as its only argument. Without further ado, I hereby present  
Module#attr\_validator:

class Module  
def attr\_validator(\*symbols, &validator)  
symbols.each do |symbol|  
define\_method “#{symbol}=” do |val|  
unless validator.call(val)  
raise ArgumentError, “Invalid value provided for #{symbol}”  
end  
instance\_variable\_set("@#{symbol}", val)  
end  
end  
end  
end

Use it, change it, polish it - it’s yours.

Cheers,  
Daniel S.

---

<div class="post-metadata">

**Author:** ![dasch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dasch](https://www.ruby-forum.com/u/dasch)\
**Post date:** [April 1, 2006, 6:06pm UTC](https://www.ruby-forum.com/t/add-a-module-attr-validator-method/56608/2 "2006-04-01T18:06:35Z")

</div>

Daniel S. wrote:

> ```
> symbols.each do |symbol|
> 
> ```
> 
> Use it, change it, polish it - it’s yours.
> 
> Cheers,  
> Daniel S.

Note that this of course only works when you actually _use_ the setter  
method, i.e. `@attr = val' will not validate`val’. Nor do I think it  
should.

Cheers,  
Daniel S.

---

<div class="post-metadata">

**Author:** ![dasch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dasch](https://www.ruby-forum.com/u/dasch)\
**Post date:** [April 1, 2006, 10:24pm UTC](https://www.ruby-forum.com/t/add-a-module-attr-validator-method/56608/3 "2006-04-01T22:24:06Z")

</div>

Thanks Daniel, I’ll give this some consideration.

A more interesting alternative that could soon come to pass is an  
extension to Facets’ annotation system. Right now one can easily do:

require ‘facet/annotation’

class Foo  
attr\_accessor :x  
ann :x, :validation =\> proc { |x| … }  
end

But this is nothing more than a note. For it to actually have any  
effect one would have to manually utilize the note. With then next  
version of annotation.rb I plan to add annotation hooks. By defining a  
hook you can automatically have it do what you would like when a  
particular annotation is define. For instance:

Annotation.annotation\_action( :validation ) { |symbol, validator|  
wrap\_method( “#{symbol}=”) { |target, x|  
unless validator.call( x )  
raise ArgumentError, “Invalid value provided for #{symbol}”  
else  
target.call(x)  
end  
}  
}

Now when you make the above annotation it will automatically generate  
the validating setter as you describe.

The only downside to this kind of thing at the moment is the lack of an  
adequate AOP foundation built into Ruby.

But all that is down the road yet. In the mean time I will likely add  
your method. Thanks.

T.

P.S. Using this list is fine, especially if you’re interested in wider  
input from the Ruby community. You can also email the Nitro list  
–Facets is a key component of Nitro/Og. And of course you can always  
email me directly.

---

<div class="post-metadata">

**Author:** ![dasch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dasch](https://www.ruby-forum.com/u/dasch)\
**Post date:** [April 2, 2006, 4:26pm UTC](https://www.ruby-forum.com/t/add-a-module-attr-validator-method/56608/4 "2006-04-02T16:26:32Z")

</div>

Trans wrote:

> end  
> raise ArgumentError, “Invalid value provided for #{symbol}”  
> adequate AOP foundation built into Ruby.
> 
> But all that is down the road yet. In the mean time I will likely add  
> your method. Thanks.
> 
> T.
> 
> P.S. Using this list is fine, especially if you’re interested in wider  
> input from the Ruby community. You can also email the Nitro list  
> –Facets is a key component of Nitro/Og. And of course you can always  
> email me directly.

Thanks for considering my idea. Personally, I like to think of a  
validator as a setter/writer that adds value validation - annotations  
just don’t fit in my perception of that process, though what you  
describe would be useful, too.

Cheers,  
Daniel S.

---

<div class="post-metadata">

**Author:** ![dasch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dasch](https://www.ruby-forum.com/u/dasch)\
**Post date:** [April 1, 2006, 10:48pm UTC](https://www.ruby-forum.com/t/add-a-module-attr-validator-method/56608/5 "2006-04-01T22:48:36Z")

</div>

On Sun, 2 Apr 2006, Trans wrote:

> end  
> raise ArgumentError, “Invalid value provided for #{symbol}”  
> adequate AOP foundation built into Ruby.
> 
> But all that is down the road yet. In the mean time I will likely add  
> your method. Thanks.
> 
> T.
> 
> P.S. Using this list is fine, especially if you’re interested in wider  
> input from the Ruby community. You can also email the Nitro list  
> –Facets is a key component of Nitro/Og. And of course you can always  
> email me directly.

fyi.

jib:~/eg/ruby/traits/traits-0.9.0 \> irb  
irb(main):001:0\> require ‘traits’  
=\> true  
irb(main):002:0\> trait :x, :validate =\> lambda{|x| Integer === x}  
=\> [[“x”, “x=”]]  
irb(main):003:0\> x  
=\> nil  
irb(main):004:0\> x 42  
=\> 42  
irb(main):005:0\> x  
=\> 42  
irb(main):006:0\> x 42.0  
ArgumentError: validation of \<42.0\> failed!  
from (eval):98:in `x=' from (eval):91:in`each’  
from (eval):91:in `x=' from (eval):3:in`send’  
from (eval):3:in `x’  
from (irb):6  
from :0

steal what you like.

regards.

-a
