caesars 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES.txt +25 -0
- data/LICENSE.txt +19 -0
- data/README.rdoc +139 -0
- data/Rakefile +66 -0
- data/bin/example +109 -0
- data/bin/example.bat +12 -0
- data/caesars.gemspec +35 -0
- data/lib/caesars.rb +95 -0
- metadata +67 -0
data/CHANGES.txt
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
CAESAR -- CHANGES
|
2
|
+
|
3
|
+
|
4
|
+
#### 0.3.2 (2009-03-04) ###############################
|
5
|
+
|
6
|
+
* FIX: Added file and line info for eval code (better debugging).
|
7
|
+
* CHANGE: The top level DSL method names are now determined by
|
8
|
+
by the class name. Some::ClassName becomes classname.
|
9
|
+
This is less confusing than allowing it to be anything
|
10
|
+
and makes it possible to use several DSLs in the same
|
11
|
+
namespace.
|
12
|
+
|
13
|
+
|
14
|
+
#### 0.3.1 (2009-03-04) ###############################
|
15
|
+
|
16
|
+
* NEW: Accept instances without a name
|
17
|
+
* CHANGE: Updated examples.
|
18
|
+
* NEW: More rdocs.
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
#### 0.3 (2009-03-04) ###############################
|
23
|
+
|
24
|
+
Initial public release
|
25
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2009 Delano Mandelbaum
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
= Caesars - v0.3
|
2
|
+
|
3
|
+
A simple class for rapid DSL prototyping in Ruby.
|
4
|
+
|
5
|
+
NOTE: Currently runs only with Ruby 1.9+!
|
6
|
+
|
7
|
+
== Installation
|
8
|
+
|
9
|
+
One of:
|
10
|
+
|
11
|
+
* gem install caesars
|
12
|
+
* copy lib/caesars.rb into your lib directory.
|
13
|
+
|
14
|
+
Or for GitHub fans:
|
15
|
+
|
16
|
+
* git clone git://github.com/delano/caesar.git
|
17
|
+
* gem sources -a http://gems.github.com (you only have to do this once, ever...), then:
|
18
|
+
* gem install delano-caesar
|
19
|
+
|
20
|
+
|
21
|
+
== Usage
|
22
|
+
|
23
|
+
|
24
|
+
# ------------------------------------------------------------------
|
25
|
+
# EXAMPLE 1 -- Flavour
|
26
|
+
#
|
27
|
+
|
28
|
+
class Flavour < Caesars # Subclass Caesars.
|
29
|
+
end
|
30
|
+
|
31
|
+
extend Flavour::DSL # Bring the DSL into the current namespace.
|
32
|
+
# This module is created dynamically based
|
33
|
+
# on the name of the subclass.
|
34
|
+
|
35
|
+
flavour do # Start drinking! I mean, start writing your
|
36
|
+
spicy true # domain specific language!
|
37
|
+
clamy true # Use any attribute name you want.
|
38
|
+
salty true
|
39
|
+
vodka :very_true # And any value you want.
|
40
|
+
end
|
41
|
+
|
42
|
+
p @flavour # => #<Flavour:0x3f56b0 ...>
|
43
|
+
p @flavour.spicy # => true
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
# ------------------------------------------------------------------
|
48
|
+
# EXAMPLE 2 -- Staff
|
49
|
+
#
|
50
|
+
|
51
|
+
# Tell Caesars which attributes have children using Caesars#bloody and
|
52
|
+
# which have blocks that you want to execute later using Caesars#virgin.
|
53
|
+
class Staff < Caesars
|
54
|
+
bloody :location
|
55
|
+
bloody :person
|
56
|
+
virgin :calculate
|
57
|
+
end
|
58
|
+
|
59
|
+
extend Staff::DSL
|
60
|
+
|
61
|
+
# The top level method is the lower case name of the class. For deeper
|
62
|
+
# names like Class::SecondLevel it will use the final name
|
63
|
+
# (i.e. secondlevel). You can supply an optional modifier name which
|
64
|
+
# will be included in the instance variable (@staff_fte).
|
65
|
+
staff :fte do
|
66
|
+
desc 'Our hard-working, "full-time" staff'
|
67
|
+
location :splashdown do
|
68
|
+
town :tsawwassen
|
69
|
+
person :steve, :sheila do
|
70
|
+
role :manager
|
71
|
+
end
|
72
|
+
person :steve do
|
73
|
+
role :cook
|
74
|
+
anger :high
|
75
|
+
hours 25
|
76
|
+
catchphrase "Rah! [strokes goatee]"
|
77
|
+
end
|
78
|
+
person :sheila do
|
79
|
+
catchphrase "This gravy tastes like food I ate in a Mexican prison."
|
80
|
+
hours rand(20)
|
81
|
+
rate "9.35/h"
|
82
|
+
calculate :salary do |gumption|
|
83
|
+
("%.2f" % [gumption * self.splashdown.sheila.rate.to_f]).to_f
|
84
|
+
end
|
85
|
+
end
|
86
|
+
person :delano do
|
87
|
+
role :cook
|
88
|
+
rate "8.35/h"
|
89
|
+
hours 57
|
90
|
+
satisfaction :low
|
91
|
+
calculate :salary do
|
92
|
+
self.splashdown.delano.rate.to_f * self.splashdown.delano.hours
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
p @staff_fte # => #<KitchenStaff: ...>
|
99
|
+
p @staff_fte.desc # => Our hard-working, "full-time" staff
|
100
|
+
|
101
|
+
# Deeper attributes are also available via instance methods
|
102
|
+
p @staff_fte.splashdown.delano # => {:role=>:cook, :rate=>"$8.35/h", :satisfaction=>:low}
|
103
|
+
p @staff_fte.splashdown.sheila # => {:role=>:manager, :catchphrase=>"This gravy tastes like food I ate in a Mexican prison."}
|
104
|
+
p @staff_fte.splashdown.steve # => {:role=>[:manager, :cook], :anger=>:high, :catchphrase=>"Rah! [strokes goatee]"}
|
105
|
+
p @staff_fte.splashdown.delano.satisfaction # => :low
|
106
|
+
|
107
|
+
# You can also access them using hash syntax
|
108
|
+
p @staff_fte.splashdown[:steve][:role] # => [:manager, :cook]
|
109
|
+
|
110
|
+
# The "bloody" attributes keep track of all values that are used. These are available as arrays
|
111
|
+
# via "NAME_values" methods. The goes for the virgin ones.
|
112
|
+
p @staff_fte.location_values # => [:splashdown]
|
113
|
+
p @staff_fte.person_values.uniq # => [:steve, :sheila, :delano, :angela]
|
114
|
+
p @staff_fte.calculate_values # => [:salary, :salary]
|
115
|
+
|
116
|
+
# The "virgin" methods store their blocks as Procs and are not executed automatically.
|
117
|
+
# You can call them manually and send arguments like you normally would.
|
118
|
+
p @staff_fte.splashdown.delano.salary.call # => 475.95
|
119
|
+
p @staff_fte.splashdown.sheila.salary.call(rand(100)) # => 549.77
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
== More Info
|
124
|
+
|
125
|
+
* GitHub[http://github.com/delano/caesar]
|
126
|
+
* Inspiration[http://www.youtube.com/watch?v=ycElb0tB9_U]
|
127
|
+
* Recipe[http://twitter.com/solutious/status/1264327499]
|
128
|
+
|
129
|
+
== Credits
|
130
|
+
|
131
|
+
* Delano Mandelbaum (delano@solutious.com)
|
132
|
+
|
133
|
+
== Thanks
|
134
|
+
|
135
|
+
* Clams, Tomatoes, Vodka, and the rest of the crew.
|
136
|
+
|
137
|
+
== License
|
138
|
+
|
139
|
+
See: LICENSE.txt
|
data/Rakefile
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/clean'
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
require 'hanna/rdoctask'
|
5
|
+
require 'fileutils'
|
6
|
+
include FileUtils
|
7
|
+
|
8
|
+
task :default => :package
|
9
|
+
|
10
|
+
# SPECS ===============================================================
|
11
|
+
|
12
|
+
# None-yet!
|
13
|
+
|
14
|
+
# PACKAGE =============================================================
|
15
|
+
|
16
|
+
name = "caesars"
|
17
|
+
load "#{name}.gemspec"
|
18
|
+
|
19
|
+
version = @spec.version
|
20
|
+
|
21
|
+
Rake::GemPackageTask.new(@spec) do |p|
|
22
|
+
p.need_tar = true if RUBY_PLATFORM !~ /mswin/
|
23
|
+
end
|
24
|
+
|
25
|
+
task :release => [ :rdoc, :package ]
|
26
|
+
|
27
|
+
task :install => [ :rdoc, :package ] do
|
28
|
+
sh %{sudo gem install pkg/#{name}-#{version}.gem}
|
29
|
+
end
|
30
|
+
|
31
|
+
task :uninstall => [ :clean ] do
|
32
|
+
sh %{sudo gem uninstall #{name}}
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
# Rubyforge Release / Publish Tasks ==================================
|
37
|
+
|
38
|
+
desc 'Publish website to rubyforge'
|
39
|
+
task 'publish:rdoc' => 'doc/index.html' do
|
40
|
+
sh "scp -rp doc/* rubyforge.org:/var/www/gforge-projects/#{name}/"
|
41
|
+
end
|
42
|
+
|
43
|
+
task 'publish:gem' => [:package] do |t|
|
44
|
+
sh <<-end
|
45
|
+
rubyforge add_release -o Any -a CHANGES.txt -f -n README.rdoc #{name} #{name} #{@spec.version} pkg/#{name}-#{@spec.version}.gem &&
|
46
|
+
rubyforge add_file -o Any -a CHANGES.txt -f -n README.rdoc #{name} #{name} #{@spec.version} pkg/#{name}-#{@spec.version}.tgz
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
Rake::RDocTask.new do |t|
|
52
|
+
t.rdoc_dir = 'doc'
|
53
|
+
t.title = @spec.summary
|
54
|
+
t.options << '--line-numbers' << '--inline-source' << '-A cattr_accessor=object'
|
55
|
+
t.options << '--charset' << 'utf-8'
|
56
|
+
t.rdoc_files.include('LICENSE.txt')
|
57
|
+
t.rdoc_files.include('README.rdoc')
|
58
|
+
t.rdoc_files.include('CHANGES.txt')
|
59
|
+
t.rdoc_files.include('bin/*')
|
60
|
+
t.rdoc_files.include('lib/*.rb')
|
61
|
+
end
|
62
|
+
|
63
|
+
CLEAN.include [ 'pkg', '*.gem', '.config', 'doc' ]
|
64
|
+
|
65
|
+
|
66
|
+
|
data/bin/example
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# Caesars Example
|
5
|
+
#
|
6
|
+
# Usage: bin/example
|
7
|
+
#
|
8
|
+
|
9
|
+
$:.unshift(File.join(File.join(File.dirname(__FILE__), '..'), 'lib')) # Make sure our local lib is first in line
|
10
|
+
|
11
|
+
require 'caesars'
|
12
|
+
|
13
|
+
# ------------------------------------------------------------------
|
14
|
+
# EXAMPLE 1 -- Flavour
|
15
|
+
#
|
16
|
+
|
17
|
+
class Flavour < Caesars # Subclass Caesars.
|
18
|
+
end
|
19
|
+
|
20
|
+
extend Flavour::DSL # Bring the DSL into the current namespace.
|
21
|
+
# This module is created dynamically based
|
22
|
+
# on the name of the subclass.
|
23
|
+
|
24
|
+
flavour do # Start drinking! I mean, start writing your
|
25
|
+
spicy true # domain specific language!
|
26
|
+
clamy true # Use any attribute name you want.
|
27
|
+
salty true
|
28
|
+
vodka :very_true # And any value you want.
|
29
|
+
end
|
30
|
+
|
31
|
+
p @flavour # => #<Flavour:0x3f56b0 ...>
|
32
|
+
p @flavour.spicy # => true
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
# ------------------------------------------------------------------
|
37
|
+
# EXAMPLE 2 -- Staff
|
38
|
+
#
|
39
|
+
|
40
|
+
# Tell Caesars which attributes have children using Caesars#bloody and
|
41
|
+
# which have blocks that you want to execute later using Caesars#virgin.
|
42
|
+
class Staff < Caesars
|
43
|
+
bloody :location
|
44
|
+
bloody :person
|
45
|
+
virgin :calculate
|
46
|
+
end
|
47
|
+
|
48
|
+
extend Staff::DSL
|
49
|
+
|
50
|
+
# The top level method is the lower case name of the class. For deeper
|
51
|
+
# names like Class::SecondLevel it will use the final name
|
52
|
+
# (i.e. secondlevel). You can supply an optional modifier name which
|
53
|
+
# will be included in the instance variable (@staff_fte).
|
54
|
+
staff :fte do
|
55
|
+
desc 'Our hard-working, "full-time" staff'
|
56
|
+
location :splashdown do
|
57
|
+
town :tsawwassen
|
58
|
+
person :steve, :sheila do
|
59
|
+
role :manager
|
60
|
+
end
|
61
|
+
person :steve do
|
62
|
+
role :cook
|
63
|
+
anger :high
|
64
|
+
hours 25
|
65
|
+
catchphrase "Rah! [strokes goatee]"
|
66
|
+
end
|
67
|
+
person :sheila do
|
68
|
+
catchphrase "This gravy tastes like food I ate in a Mexican prison."
|
69
|
+
hours rand(20)
|
70
|
+
rate "9.35/h"
|
71
|
+
calculate :salary do |gumption|
|
72
|
+
("%.2f" % [gumption * self.splashdown.sheila.rate.to_f]).to_f
|
73
|
+
end
|
74
|
+
end
|
75
|
+
person :delano do
|
76
|
+
role :cook
|
77
|
+
rate "8.35/h"
|
78
|
+
hours 57
|
79
|
+
satisfaction :low
|
80
|
+
calculate :salary do
|
81
|
+
self.splashdown.delano.rate.to_f * self.splashdown.delano.hours
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
p @staff_fte # => #<KitchenStaff: ...>
|
88
|
+
p @staff_fte.desc # => Our hard-working, "full-time" staff
|
89
|
+
|
90
|
+
# Deeper attributes are also available via instance methods
|
91
|
+
p @staff_fte.splashdown.delano # => {:role=>:cook, :rate=>"$8.35/h", :satisfaction=>:low}
|
92
|
+
p @staff_fte.splashdown.sheila # => {:role=>:manager, :catchphrase=>"This gravy tastes like food I ate in a Mexican prison."}
|
93
|
+
p @staff_fte.splashdown.steve # => {:role=>[:manager, :cook], :anger=>:high, :catchphrase=>"Rah! [strokes goatee]"}
|
94
|
+
p @staff_fte.splashdown.delano.satisfaction # => :low
|
95
|
+
|
96
|
+
# You can also access them using hash syntax
|
97
|
+
p @staff_fte.splashdown[:steve][:role] # => [:manager, :cook]
|
98
|
+
|
99
|
+
# The "bloody" attributes keep track of all values that are used. These are available as arrays
|
100
|
+
# via "NAME_values" methods. The goes for the virgin ones.
|
101
|
+
p @staff_fte.location_values # => [:splashdown]
|
102
|
+
p @staff_fte.person_values.uniq # => [:steve, :sheila, :delano, :angela]
|
103
|
+
p @staff_fte.calculate_values # => [:salary, :salary]
|
104
|
+
|
105
|
+
# The "virgin" methods store their blocks as Procs and are not executed automatically.
|
106
|
+
# You can call them manually and send arguments like you normally would.
|
107
|
+
p @staff_fte.splashdown.delano.salary.call # => 475.95
|
108
|
+
p @staff_fte.splashdown.sheila.salary.call(rand(100)) # => 549.77
|
109
|
+
p @staff_fte.splashdown.keys
|
data/bin/example.bat
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
@echo off
|
2
|
+
|
3
|
+
rem Check for funkiness when called from another batch script.
|
4
|
+
rem We want FULL_PATH to contain the full path to the stella bin directory.
|
5
|
+
IF EXIST "%~dp0example.bat" (set FULL_PATH=%~dp0) ELSE (set FULL_PATH=%~dp$PATH:0)
|
6
|
+
|
7
|
+
rem Check for JRuby, otherwise use Ruby.
|
8
|
+
rem We want EXECUTABLE to contain either "jruby" or "ruby"
|
9
|
+
IF EXIST "%JRUBY_HOME%" (set EXECUTABLE=jruby) ELSE (set EXECUTABLE=ruby)
|
10
|
+
|
11
|
+
rem Call the Ruby script, passing it all the arguments.
|
12
|
+
@%EXECUTABLE% %FULL_PATH%example %*
|
data/caesars.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
@spec = Gem::Specification.new do |s|
|
2
|
+
s.name = %q{caesars}
|
3
|
+
s.version = "0.3.2"
|
4
|
+
s.date = %q{2009-03-04}
|
5
|
+
s.specification_version = 1 if s.respond_to? :specification_version=
|
6
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
7
|
+
|
8
|
+
s.authors = ["Delano Mandelbaum"]
|
9
|
+
s.description = %q{A simple class for rapid DSL prototyping in Ruby.}
|
10
|
+
s.summary = %q{Caesars: A simple class for rapid DSL prototyping in Ruby.}
|
11
|
+
s.email = %q{delano@solutious.com}
|
12
|
+
|
13
|
+
# = MANIFEST =
|
14
|
+
# git ls-files
|
15
|
+
s.files = %w(
|
16
|
+
CHANGES.txt
|
17
|
+
LICENSE.txt
|
18
|
+
README.rdoc
|
19
|
+
Rakefile
|
20
|
+
bin/example
|
21
|
+
bin/example.bat
|
22
|
+
caesars.gemspec
|
23
|
+
lib/caesars.rb
|
24
|
+
)
|
25
|
+
|
26
|
+
# s.add_dependency ''
|
27
|
+
|
28
|
+
s.has_rdoc = true
|
29
|
+
s.homepage = %q{http://github.com/delano/caesar}
|
30
|
+
s.extra_rdoc_files = %w[README.rdoc LICENSE.txt CHANGES.txt]
|
31
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Caesars: A simple class for rapid DSL prototyping in Ruby.", "--main", "README.rdoc"]
|
32
|
+
s.require_paths = ["lib"]
|
33
|
+
s.rubygems_version = %q{1.1.1}
|
34
|
+
s.rubyforge_project = "caesars"
|
35
|
+
end
|
data/lib/caesars.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
|
2
|
+
# Caesars -- A simple class for rapid DSL prototyping.
|
3
|
+
#
|
4
|
+
# Subclass Caesars, then tell it which attributes have children using
|
5
|
+
# Caesars.bloody and which have blocks that you want to execute later
|
6
|
+
# using Caesars.virgin. That's it! Just start drinking! I mean, start
|
7
|
+
# writing your domain specific language!
|
8
|
+
#
|
9
|
+
# See README.rdoc for a usage example.
|
10
|
+
#
|
11
|
+
class Caesars
|
12
|
+
VERSION = "0.3.2"
|
13
|
+
# A subclass of ::Hash that provides method names for hash parameters.
|
14
|
+
# It's like a lightweight OpenStruct.
|
15
|
+
# ch = Caesars::Hash[:tabasco => :lots!]
|
16
|
+
# puts ch.tabasco # => lots!
|
17
|
+
#
|
18
|
+
class Hash < ::Hash
|
19
|
+
def method_missing(meth)
|
20
|
+
(self.has_key?(meth)) ? self[meth] : nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
# An instance of Caesars::Hash which contains the data specified by your DSL
|
24
|
+
attr_accessor :caesars_properties
|
25
|
+
# Creates an instance of Caesars.
|
26
|
+
# +name+ is .
|
27
|
+
def initialize(name=nil)
|
28
|
+
@caesars_name = name if name
|
29
|
+
@caesars_properties = Caesars::Hash.new
|
30
|
+
@caesars_pointer = @caesars_properties
|
31
|
+
end
|
32
|
+
# This method handles all of the attributes that do not contain blocks.
|
33
|
+
def method_missing(name, *args, &b)
|
34
|
+
return @caesars_properties[name] if @caesars_properties.has_key?(name) && args.empty? && b.nil?
|
35
|
+
if @caesars_pointer[name]
|
36
|
+
@caesars_pointer[name] = [@caesars_pointer[name]] unless @caesars_pointer[name].is_a?(Array)
|
37
|
+
@caesars_pointer[name] += args
|
38
|
+
elsif !args.empty?
|
39
|
+
@caesars_pointer[name] = args.size == 1 ? args.first : args
|
40
|
+
end
|
41
|
+
end
|
42
|
+
# see bin/example for usage.
|
43
|
+
def self.virgin(meth)
|
44
|
+
self.bloody(meth, false)
|
45
|
+
end
|
46
|
+
# see bin/example for usage.
|
47
|
+
def self.bloody(meth, execute=true)
|
48
|
+
define_method(meth) do |*names,&b| # |*names,&b| syntax does not parse in Ruby 1.8
|
49
|
+
all = instance_variable_get("@" << meth.to_s) || []
|
50
|
+
|
51
|
+
names.each do |name|
|
52
|
+
instance_variable_set("@" << meth.to_s, all << name)
|
53
|
+
|
54
|
+
if execute
|
55
|
+
prev = @caesars_pointer
|
56
|
+
@caesars_pointer[name] ||= Caesars::Hash.new
|
57
|
+
@caesars_pointer = @caesars_pointer[name]
|
58
|
+
b.call if b
|
59
|
+
@caesars_pointer = prev
|
60
|
+
else
|
61
|
+
@caesars_pointer[name] = b
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
define_method("#{meth}_values") do ||
|
68
|
+
instance_variable_get("@" << meth.to_s) || []
|
69
|
+
end
|
70
|
+
end
|
71
|
+
# Executes automatically when Caesars is subclassed. This creates the
|
72
|
+
# YourClass::DSL module which contains a single method: method_missing.
|
73
|
+
# This is used to catch the top level DSL method. That's why you can
|
74
|
+
# used any method name you like.
|
75
|
+
def self.inherited(modname)
|
76
|
+
meth = (modname.to_s.split(/::/))[-1].downcase # Some::ClassName => classname
|
77
|
+
module_eval %Q{
|
78
|
+
module #{modname}::DSL
|
79
|
+
def #{meth}(*args, &b)
|
80
|
+
name = !args.empty? ? args.first.to_s : nil
|
81
|
+
varname = "@#{meth.to_s}"
|
82
|
+
varname << "_\#{name}" if name
|
83
|
+
i = instance_variable_set(varname, #{modname.to_s}.new(name))
|
84
|
+
i.instance_eval(&b) if b
|
85
|
+
i
|
86
|
+
end
|
87
|
+
end
|
88
|
+
}, __FILE__, __LINE__
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: caesars
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Delano Mandelbaum
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-03-04 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: A simple class for rapid DSL prototyping in Ruby.
|
17
|
+
email: delano@solutious.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
- LICENSE.txt
|
25
|
+
- CHANGES.txt
|
26
|
+
files:
|
27
|
+
- CHANGES.txt
|
28
|
+
- LICENSE.txt
|
29
|
+
- README.rdoc
|
30
|
+
- Rakefile
|
31
|
+
- bin/example
|
32
|
+
- bin/example.bat
|
33
|
+
- caesars.gemspec
|
34
|
+
- lib/caesars.rb
|
35
|
+
has_rdoc: true
|
36
|
+
homepage: http://github.com/delano/caesar
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options:
|
39
|
+
- --line-numbers
|
40
|
+
- --inline-source
|
41
|
+
- --title
|
42
|
+
- "Caesars: A simple class for rapid DSL prototyping in Ruby."
|
43
|
+
- --main
|
44
|
+
- README.rdoc
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project: caesars
|
62
|
+
rubygems_version: 1.2.0
|
63
|
+
signing_key:
|
64
|
+
specification_version: 1
|
65
|
+
summary: "Caesars: A simple class for rapid DSL prototyping in Ruby."
|
66
|
+
test_files: []
|
67
|
+
|