Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/delano/caesars

Rapid and delicious DSL prototyping in Ruby (NOT MAINTAINED)
https://github.com/delano/caesars

Last synced: about 2 months ago
JSON representation

Rapid and delicious DSL prototyping in Ruby (NOT MAINTAINED)

Awesome Lists containing this project

README

        

= Caesars - v0.7

A simple class for rapid DSL prototyping in Ruby.

NOTE: Post-processing of Caesars::Config subclasses changed in 0.7. In 0.6 and earlier, the post-processing hook (Caesars::Config#postprocess) was called after every file was loaded. In 0.7 it's called after all files have been loaded. This could break some highly dependent code in your subclasses of Caesars::Config so I apologize but I believe this is the right thing to do. If you are not satisfied with that apology, prepare yourself a caesar or bloody mary or any other beverage and send email me with the details!

== Installation

One of:

* gem install caesars
* copy lib/caesars.rb into your lib directory.

Or for GitHub fans:

* gem install delano-caesars --source http://gems.github.com
* git clone git://github.com/delano/caesar.git

== EXAMPLE 1 -- A Simple DSL

require 'caesars'

class Flavour < Caesars # Subclass Caesars.
end

extend Flavour::DSL # Bring the DSL into the current namespace.
# This module is created dynamically based
# on the name of the subclass.

flavour do # Start drinking! I mean, start writing your
spicy true # domain specific language!
clamy true # Use any attribute name you want.
salty true
vodka :very_true # And any value you want.
end

p @flavour # => #
p @flavour.spicy # => true

== EXAMPLE 2 -- Storing Blocks as Procs

require 'caesars'

class Staff < Caesars

chill :calculate # Delay execution of the blocks for the calculate
# attribute. They will be stored as Procs.
end

extend Staff::DSL

# The top level method is the lower case name of the class. For deeper
# names like Class::SecondLevel it will use the final name
# (i.e. secondlevel). You can supply an optional modifier name which
# will be included in the instance variable (@staff_fte).
staff :fte do
desc 'Our hard-working, "full-time" staff'

location :splashdown do
town :tsawwassen

person :steve, :sheila do
role :manager
end

person :steve do
role :cook
anger :high
hours 25
catchphrase "Rah! [strokes goatee]"
end

person :sheila do
catchphrase "This gravy tastes like food I ate in a Mexican prison."
hours rand(20)
rate "9.35/h"
calculate :salary do |gumption|
("%.2f" % [gumption * self.splashdown.sheila.rate.to_f]).to_f
end
end

person :delano do
role :cook
rate "8.35/h"
hours 57
satisfaction :low
calculate :salary do
self.splashdown.delano.rate.to_f * self.splashdown.delano.hours
end
end

end
end

p @staff_fte # => #
p @staff_fte.desc # => Our hard-working, "full-time" staff

# Deeper attributes are also available via instance methods
p @staff_fte.splashdown.delano # => {:role=>:cook, :rate=>"$8.35/h", :satisfaction=>:low}
p @staff_fte.splashdown.sheila # => {:role=>:manager, :catchphrase=>"This gravy tastes like food I ate in a Mexican prison."}
p @staff_fte.splashdown.steve # => {:role=>[:manager, :cook], :anger=>:high, :catchphrase=>"Rah! [strokes goatee]"}
p @staff_fte.splashdown.delano.satisfaction # => :low

# You can also access them using hash syntax
p @staff_fte.splashdown[:steve][:role] # => [:manager, :cook]

# The "chilled" attributes store their blocks as Procs and are not executed automatically.
# You can call them manually and send arguments like you normally would.
p @staff_fte.splashdown.delano.salary.call # => 475.95
p @staff_fte.splashdown.sheila.salary.call(rand(100)) # => 549.77

== EXAMPLE 3 -- External Config Files

require 'caesars'

class Food < Caesars
chill :order
end
class Drink < Caesars
end

class PartyConfig < Caesars::Config
dsl Food::DSL
dsl Drink::DSL
end

conffile = File.join(File.dirname(__FILE__), 'party.conf')
@config = PartyConfig.new(conffile)

p @config.food.order.call # => 10kg
p @config[:drink][:wine] # => 12L
p @config # =>
p @config.keys # => [:food, :drink]

# [... make changes to party.conf ...]

@config.refresh

*party.conf*

food do
oysters "10kg"
order do
self.oysters
end
end

drink do
wine "12L"
end

== More Info

* GitHub[http://github.com/delano/caesars]
* Inspiration[http://www.youtube.com/watch?v=ycElb0tB9_U]
* Recipe[http://twitter.com/solutious/status/1264327499]

== Credits

* OrderedHash implementation by jan molic
* Delano Mandelbaum ([email protected])

== Thanks

* Clams, Tomatoes, Grey Goose, and the rest of the crew.
* Caleb Buxton (http://cpb.ca) for early feedback.
* Solutious Inc (http://solutious.com)

== Related Projects

* DSLify[http://github.com/auser/dslify]

== License

See: LICENSE.txt