# ANN: doodle 0.0.1

**URL:** <https://www.ruby-forum.com/t/ann-doodle-0-0-1/131376>\
**Category:** Ruby\
**Created:** [March 9, 2008, 12:13am UTC](https://www.ruby-forum.com/t/ann-doodle-0-0-1/131376 "2008-03-09T00:13:44Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![sean](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/f0a364/32.png) [@sean](https://www.ruby-forum.com/u/sean)\
**Post date:** [March 9, 2008, 12:13am UTC](https://www.ruby-forum.com/t/ann-doodle-0-0-1/131376/1 "2008-03-09T00:13:44Z")

</div>

Doodle is a Ruby library and gem for simplifying the definition of  
Ruby classes by making attributes and their properties more  
declarative.

Doodle is eco-friendly – it does not globally modify Object, Class or  
Module, nor does it pollute instances with its own instance variables  
(i.e. it plays nice with yaml). Future versions will try to be even  
more unobtrusive.

It is similar to but different from libraries such as Ara Howard’s  
attributes and traits and likewise owes something to the famous  
metakoans Ruby quiz.

Features:

```
* initialization
      o using positional arguments
      o with named arguments
      o by block
* defaults
* initial values
* validation at attribute and class levels
* conversions for attributes and classes
* collectors to help in defining simple DSLs
* works for classes, instances and singletons

```

Putting all this together, you can initialize objects like this:

event = Event “Festival” do  
date ‘2008-04-01’  
place “The muddy field”  
place “Beer tent” do  
event “Drinking”  
end  
end

pp event

#\<Event:0x595394  
@date=#\<Date: 4909115/2,0,2299161\>,  
@locations=  
[#\<Location:0x5913d4 @events=[], @name=“The muddy field”\>,  
#\<Location:0x58ef58  
@events=[#\<Event:0x58d630 @locations=[], @name=“Drinking”\>],  
@name=“Beer tent”\>],  
@name=“Festival”\>

from a class definition like this:

require ‘date’  
require ‘pp’  
require ‘doodle’

class Location \< Doodle::Base  
has :name, :kind =\> String  
has :events, :init =\> [], :collect =\> :Event  
end

class Event \< Doodle::Base  
has :name, :kind =\> String  
has :date do  
kind Date  
default { Date.today }  
must ‘be \>= today’ do |value|  
value \>= Date.today  
end  
from String do |s|  
Date.parse(s)  
end  
end  
has :locations, :init =\> [], :collect =\> {:place =\> “Location”}  
end

To install:

$ sudo gem install doodle

or

C:\> gem install doodle

For more info, see [http://doodle.rubyforge.org/](http://doodle.rubyforge.org/)

---

<div class="post-metadata">

**Author:** ![sean](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/f0a364/32.png) [@sean](https://www.ruby-forum.com/u/sean)\
**Post date:** [March 9, 2008, 6:45am UTC](https://www.ruby-forum.com/t/ann-doodle-0-0-1/131376/2 "2008-03-09T06:45:16Z")

</div>

From: Sean O’Halpin [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]

# \* initialization

# o using positional arguments

# o with named arguments

# o by block

# \* defaults

# \* initial values

# \* validation at attribute and class levels

# \* conversions for attributes and classes

# \* collectors to help in defining simple DSLs

# \* works for classes, instances and singletons

wow, at 0.0.1 version, that is awesome power.  
downloading gem now…

kind regards -botp

---

<div class="post-metadata">

**Author:** ![sean](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/f0a364/32.png) [@sean](https://www.ruby-forum.com/u/sean)\
**Post date:** [March 10, 2008, 12:08pm UTC](https://www.ruby-forum.com/t/ann-doodle-0-0-1/131376/3 "2008-03-10T12:08:45Z")

</div>

On 08/03/2008, Sean O’Halpin [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> from a class definition like this:
> 
> class Location \< Doodle::Base  
> has :name, :kind =\> String  
> has :events, :init =\> [], :collect =\> :Event  
> end

Are there any cases where you’d want to use “collect”, but not “:init =\>  
[]” ?

I think it’d also be really interesting to hear if you were using this  
library for anything specific - importing data, for example?

Looks very interesting though!

---

<div class="post-metadata">

**Author:** ![sean](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/f0a364/32.png) [@sean](https://www.ruby-forum.com/u/sean)\
**Post date:** [March 12, 2008, 3:14am UTC](https://www.ruby-forum.com/t/ann-doodle-0-0-1/131376/4 "2008-03-12T03:14:00Z")

</div>

Hi James!

On Mon, Mar 10, 2008 at 11:08 AM, James A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Are there any cases where you’d want to use “collect”, but not “:init =\> []” ?

:collect works for anything that provides a :\<\< method, though I’ve  
only tested it with Array, String, StringIO and Set.  
But initializing with an Array if you use :collect on its own without  
specifying an initial value might be useful (though I’m not keen to  
have too much ‘magic’ in there).

> I think it’d also be really interesting to hear if you were using this  
> library for anything specific - importing data, for example?

Funny you should mention that 🙂 One use is for validating  
quasi-freeform text records of the form:

field1: value  
field2: value

field1: value  
field2: value

where both field and value have to be validated as well as the whole  
record once assembled.

Another is for config files (sometimes yaml just gets too confusing  
and you still have to validate anyway).  
A colleague at work is using it for a DSL (which is where the Event  
example comes from and what prompted me to release it as a gem).

> Looks very interesting though!

Well, it’s been keeping me occupied through the cold winter nights 🙂

Best regards,  
Sean

---

<div class="post-metadata">

**Author:** ![sean](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/f0a364/32.png) [@sean](https://www.ruby-forum.com/u/sean)\
**Post date:** [March 14, 2008, 11:51pm UTC](https://www.ruby-forum.com/t/ann-doodle-0-0-1/131376/5 "2008-03-14T23:51:46Z")

</div>

Very cool. Any thoughts on serializing/persisting Doodle objects?

Aman G.

---

<div class="post-metadata">

**Author:** ![sean](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/f0a364/32.png) [@sean](https://www.ruby-forum.com/u/sean)\
**Post date:** [March 15, 2008, 2:52pm UTC](https://www.ruby-forum.com/t/ann-doodle-0-0-1/131376/6 "2008-03-15T14:52:01Z")

</div>

On Fri, Mar 14, 2008 at 10:51 PM, Aman G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Very cool. Any thoughts on serializing/persisting Doodle objects?
> 
> Aman G.

Well, you can serialize using YAML, e.g. using the example class  
definition from the original post:

str = event.to\_yaml  
loaded\_event = YAML::load(str)

However, this bypasses validation (because YAML::load works on the  
@instance\_variable level rather than accessor level).  
I’ve just uploaded a newer version of doodle (0.0.4) that makes public  
the validate! method and adds a option all=true|false to force  
validation of all attributes. So you could load a dodgy YAML file and  
validate it like this:

another\_event = YAML::load(DATA.read)  
another\_event.validate!(true)

validate! will raise a Doodle::ValidationError if any validations are  
violated. (The exclamation mark denotes possible exception ahead.) I’m  
not entirely happy about this interface so it will probably change to  
just validate! in the next version (with no flag).

The same method should work for any other low level loaders.

The next phase of work on doodle will be to see how well I can  
integrate it with other libraries (like Sequel or Ambition for  
example).

Regards,  
Sean
