Project

caesars

0.01
No commit activity in last 3 years
No release in over 3 years
Rapid DSL prototyping in Ruby.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies
 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 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              # => #<Flavour:0x3f56b0 ...>
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                    # => #<Staff: ...>
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                   # => <PartyConfig:0x3f780c ...>
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¶ ↑

Credits¶ ↑

  • OrderedHash implementation by jan molic

  • Delano Mandelbaum (delano@solutious.com)

Thanks¶ ↑

  • Clams, Tomatoes, Grey Goose, and the rest of the crew.

  • Caleb Buxton (cpb.ca) for early feedback.

  • Solutious Inc (solutious.com)

Related Projects¶ ↑

License¶ ↑

See: LICENSE.txt